无法使用Xib将类型UIView的值转换为[CustomView]

时间:2017-11-19 22:13:52

标签: swift uiview nib

我已经看过很多类似的问题,但很多都不是最新的,没有一个能解决我的问题。

我有一个自定义Xib和类CardView。当我尝试在代码中实例化它时,我得到Could not cast value of type 'UIView' to 'CardView'

课程如下:

class CardView: NibView {

    @IBOutlet var contentView: UIView!
    @IBOutlet weak var wordLabel: UILabel!
    @IBOutlet weak var flipButton: UIButton!
    @IBOutlet weak var playButton: UIButton!

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit() {
        Bundle.main.loadNibNamed("CardView", owner: self, options: nil)
        addSubview(contentView)
        contentView.frame = self.bounds
        contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]

    }

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

NibView是一个自定义超类,看起来像:

class NibView: UIView {
    var view: UIView!
    override init(frame: CGRect) {
        super.init(frame: frame)

        // Setup view from .xib file
        xibSetup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        // Setup view from .xib file
        xibSetup()
    }
}
private extension NibView {

    func xibSetup() {
        backgroundColor = UIColor.white
        view = loadNib()
        // use bounds not frame or it'll be offset
        view.frame = bounds
        // Adding custom subview on top of our view
        addSubview(view)

        view.translatesAutoresizingMaskIntoConstraints = false
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[childView]|",
                                                      options: [],
                                                      metrics: nil,
                                                      views: ["childView": view]))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[childView]|",
                                                      options: [],
                                                      metrics: nil,
                                                      views: ["childView": view]))
    }
}

extension UIView {
    /** Loads instance from nib with the same name. */
    func loadNib() -> UIView {
        let bundle = Bundle(for: type(of: self))
        let nibName = type(of: self).description().components(separatedBy: ".").last!
        let nib = UINib(nibName: nibName, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as! UIView
    }
}

以下是我的文件检查器的屏幕截图,显示我将File的所有者自定义类设置为CardView,这似乎是许多人的绊脚石 Here is a screenshot of my file inspector showing that I set the File's Owner custom class to CardView, which seems to be a stumbling block for many

最后,我尝试按如下方式实例化CardViewCardView().loadNib() as! CardView

4 个答案:

答案 0 :(得分:0)

旧问题,但万一有人在这里

我的问题是视图子类为fileprivate。 IB显然不喜欢这样。

答案 1 :(得分:0)

UIViewController中,当您创建CardView的实例时,而不是像CardView().loadNib() as! CardView那样强制转换,而是调用函数object_setClass(_, _)以避免该错误( Xcode 9)。

所以应该像这样:

let myCardView = CardView().loadNib
object_setClass(myCardView, CardView.self)
view.addSubview(myCardView)

答案 2 :(得分:0)

万一有人仍然有这个问题,我也有同样的问题,我想我们遵循相同的教程。

您在loadNib()中打过xibSetup()。我认为您不必再​​次调用它。

所以不要使用

let myCardView = CardView().loadNib() as! CardView

我只是用

let myCardView = CardView()

答案 3 :(得分:0)

对我来说,以这种方式以编程方式加载xib不起作用。我必须删除文件所有者的类名,并将其设置为第一个视图的类名。然后,我必须为要使用的组件设置插座。

stdout

添加到网点后的自定义视图类中。对您来说,它是 CardView 。然后我加载了

这样的视图类
required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
}
override init(frame: CGRect) {
    super.init(frame: frame)
}