Swift 为什么无法强制转换类型为';UIView&x27;换个角度看?

Swift 为什么无法强制转换类型为';UIView&x27;换个角度看?,swift,uiview,casting,Swift,Uiview,Casting,这个问题涉及的代码与我前面的问题相同 (上一个问题是) 但是完全不同的方法 这不是重复的问题 因此,让我重新构造我的问题 首先,让我总结一下我的项目 由于前面的回答,我现在可以重用xib了。 这是CardContentView.xib 代码如下 @IBDesignable class CardContentView: UIView { @IBOutlet weak var backgroundView: UIView! @IBInspectable var nibName:

这个问题涉及的代码与我前面的问题相同
(上一个问题是)
但是完全不同的方法
这不是重复的问题
因此,让我重新构造我的问题

首先,让我总结一下我的项目

由于前面的回答,我现在可以重用xib了。 这是CardContentView.xib

代码如下

@IBDesignable class CardContentView: UIView {

    @IBOutlet weak var backgroundView: UIView!

    @IBInspectable var nibName:String?
    var contentView: UIView?


    override func awakeFromNib() {
        super.awakeFromNib()
        xibSetup()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        xibSetup()
        contentView?.prepareForInterfaceBuilder()
    }


    func xibSetup(){
        guard let view = loadViewFromNib() else { return }
        view.frame = self.bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(view)
        contentView = view
    }


    func loadViewFromNib() -> UIView? {
        guard let nibName = nibName else { return nil }
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nibName, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as? UIView
    }
}
class CardView: UIView {

    @IBOutlet weak var cardContentView: CardContentView!

    override func awakeFromNib() {
        cardContentView.layer.cornerRadius = 16
    }
}
class ViewController: UIViewController {

    @IBOutlet weak var cardView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
这是cardwiew.xib,属性位于“class CardContentView”之后

代码如下

@IBDesignable class CardContentView: UIView {

    @IBOutlet weak var backgroundView: UIView!

    @IBInspectable var nibName:String?
    var contentView: UIView?


    override func awakeFromNib() {
        super.awakeFromNib()
        xibSetup()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        xibSetup()
        contentView?.prepareForInterfaceBuilder()
    }


    func xibSetup(){
        guard let view = loadViewFromNib() else { return }
        view.frame = self.bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(view)
        contentView = view
    }


    func loadViewFromNib() -> UIView? {
        guard let nibName = nibName else { return nil }
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nibName, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as? UIView
    }
}
class CardView: UIView {

    @IBOutlet weak var cardContentView: CardContentView!

    override func awakeFromNib() {
        cardContentView.layer.cornerRadius = 16
    }
}
class ViewController: UIViewController {

    @IBOutlet weak var cardView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
这是主故事板。只有一个视图。

代码如下

@IBDesignable class CardContentView: UIView {

    @IBOutlet weak var backgroundView: UIView!

    @IBInspectable var nibName:String?
    var contentView: UIView?


    override func awakeFromNib() {
        super.awakeFromNib()
        xibSetup()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        xibSetup()
        contentView?.prepareForInterfaceBuilder()
    }


    func xibSetup(){
        guard let view = loadViewFromNib() else { return }
        view.frame = self.bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(view)
        contentView = view
    }


    func loadViewFromNib() -> UIView? {
        guard let nibName = nibName else { return nil }
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nibName, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as? UIView
    }
}
class CardView: UIView {

    @IBOutlet weak var cardContentView: CardContentView!

    override func awakeFromNib() {
        cardContentView.layer.cornerRadius = 16
    }
}
class ViewController: UIViewController {

    @IBOutlet weak var cardView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
但是,我想在ViewController中将类“CardView”重用为“CardView”属性
我想将'background'属性改为'cardwiew'属性(简单地说,我想在CardContentView中将黄色框改为蓝色框!)
我想使“cardView”属性具有过渡效果
但是,我无法进行扩展,因为它不在UIView类中,而是在ViewController类中
所以我需要制作另一个UIView类
这就是为什么我单独制作了一个CardView类
(当然,我希望通过创建另一个文件来整齐地组织代码。)

所以,我尝试了两种不同的方法

  • 将属性“cardView”类设置为cardView,并将其连接到ViewController

    class ViewController: UIViewController {
    
        @IBOutlet weak var cardView: CardView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    }
    
  • 将“CardView”类强制转换为ViewController中的其他属性

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let tappedView = self.cardView as! CardView
        self.view.addSubview(tappedView)    
    }
    
  • 但他们都会犯错误
    1.当我制作“@ibvar-cardwiew:cardwiew!”时,它抛出错误消息,“在展开可选值cardContentView=nil时意外发现nil”
    2.当我制作“let tappedView=self.cardView as!”!CardView'会引发错误消息,“无法将类型为'UIView'(0x10a229ff8)的值强制转换为'awakefromnibtuitorial.CardView'(0x1060aa8d0)。”

    我怎样才能解决这个问题
    请帮帮我

    • 在CardView类的
      awakeFromNib()
      中,您没有调用
      super.awakeFromNib()
    • 您必须使用与从其相应的XIB加载CardContentView相同的逻辑(
      xibSetup()
      ),才能从其XIB加载CardView
    • 在故事板的ViewController中,您是否已将UIView的类指定给CardView

    1。“super.awakeFromNib()”2仍然弹出错误。怎样?3.当然,是我指定的。我尝试过,但仍然抛出“cardContentView=nil”加上“contentView=nil”,对于CardView,在IB中,您似乎已将类名分配给UIView,而不是文件的所有者。试着更新一下。更新什么?在CardView.xib中,没有文件的所有者,将默认视图的类设置为“CardView”,将UIView类设置为“CardContentView”。