Ctibor Šebák
Ctibor Šebák

Reputation: 133

Canot assign value of type 'UIView' to type --class conforming to UIView--

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

Answers (3)

qRis
qRis

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

Rakesha Shastri
Rakesha Shastri

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

David Pasztor
David Pasztor

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

Related Questions