Reputation: 133
I have the following class conforming to UIView:
import UIKit
class LocationInformationCalloutView: UIView {
:
:
Then I have a second class that looks like this:
class LocationInformationAnnotationView: MKAnnotationView {
weak var customCalloutView : LocationInformationCalloutView?
}
}
:
:
So you can see I have a variable called customAnnotationView
that is of type LocationInformationCalloutView
which is of type UIView
The loadLocationInformationCalloutView()
function looks like this (just a function that returns an UIView):
func loadLocationInformationCalloutView() -> UIView? {
let view = UIView(frame: CGRect(x: 0, y: 0, width: 240, height: 280))
return view
}
However upon invoking this line of code:
self.customCalloutView = newCustomCalloutView
within this block of code:
override func setSelected(_ selected: Bool, animated: Bool) {
if selected {
self.customCalloutView?.removeFromSuperview()
if let newCustomCalloutView = loadLocationInformationCalloutView() {
newCustomCalloutView.frame.origin.x -= newCustomCalloutView.frame.width / 2.0 - (self.frame.width / 2.0)
newCustomCalloutView.frame.origin.y -= newCustomCalloutView.frame.height
self.addSubview(newCustomCalloutView)
self.customCalloutView = newCustomCalloutView
if animated {
self.customCalloutView!.alpha = 0.0
UIView.animate(withDuration: 1.8, animations: {
self.customCalloutView!.alpha = 1.0
})
I get the following error:
Cannot assign value of type 'UIView' to type 'LocationInformationnCalloutView?'
Can someone shed some light on this and help me through this problem? Any help si greatly appreciated, thanks!
Upvotes: 0
Views: 1477
Reputation: 86
Did you try to instantiate the CalloutView with its own classtype like this:
func loadLocationInformationCalloutView() -> LocationInformationCalloutView? {
let view = LocationInformationCalloutView(frame: CGRect(x: 0, y: 0, width: 240, height: 280))
return view
}
Upvotes: 0
Reputation: 11243
You got it the other way around. You can assign a variable of a subclass to a variable of a superclass, but you can't do the opposite for obvious reasons.
First thing, you method should be returning a valid LocationInformationCalloutView
if it is supposed to that. If you have to, for some reason return it as a UIView
. Then you have to cast it to LocationInformationCalloutView
before saving it in customCalloutView
.
if let validCustomCalloutView = newCustomCalloutView as? LocationInformationCalloutView {
self.customCalloutView = validCustomCalloutView
}
Note: The casting will fail if the UIView
being passed is not actually an instance of LocationInformationCalloutView
. The method should preferably look like how @DávidPásztor answer shows.
Upvotes: 1
Reputation: 54706
LocationInformationCalloutView
inherits from UIView
, which means that you can assign an instance of LocationInformationCalloutView
to a property whose type is UIView
, but you cannot do so the other way around.
At the line self.customCalloutView = newCustomCalloutView
you are trying to assign a UIView
instance to a property of type LocationInformationCalloutView
, which cannot work, since a parent class cannot be used in place of a child instance.
You need to change the return type of loadLocationInformationCalloutView()
to be LocationInformationCalloutView
instead of UIView
.
func loadLocationInformationCalloutView() -> LocationInformationCalloutView {
return LocationInformationCalloutView(frame: CGRect(x: 0, y: 0, width: 240, height: 280))
}
Upvotes: 1