【问题标题】:Could not cast value of type UIView to [CustomView] using Xib无法使用 Xib 将 UIView 类型的值转换为 [CustomView]
【发布时间】:2018-05-03 02:44:54
【问题描述】:

我见过很多类似的问题,但很多都不是最新的,也没有解决我的问题。

我有一个自定义 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's Owner 自定义类设置为 CardView,这似乎是许多人的绊脚石

最后,我尝试将CardView 实例化如下:CardView().loadNib() as! CardView

【问题讨论】:

标签: swift uiview nib


【解决方案1】:

如果有人仍然有这个问题,我有同样的问题,我认为我们遵循相同的教程。

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

所以不要使用

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

我只是用

let myCardView = CardView()

【讨论】:

    【解决方案2】:

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

    所以应该是这样的:

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

    【讨论】:

      【解决方案3】:

      老问题,但万一有人在这里:

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

      【讨论】:

        【解决方案4】:

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

        required init(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)!
        }
        override init(frame: CGRect) {
            super.init(frame: frame)
        }
        

        在出口之后添加到自定义视图类。对您来说,它是 CardView。然后我像

        这样加载了那个视图类
        let viewCard = Bundle.main.loadNibNamed("CardView", owner: self, options: nil)?.first as! CardView
        view.addSubview(viewCard)
        

        【讨论】:

        • 那么怎么设置网点呢?我没有关注..如果您没有所有者课程,则无法连接插座。我错过了什么?
        • 对于自定义 .xib 文件,仅将 .swift 文件名设置为第一次查看并将文件所有者的类保持为默认(空)就足以设置 outlet。然后你的助理编辑会协助你设置网点。确保将 .swift 文件名设置为层次结构中最顶层的视图。
        猜你喜欢
        • 2016-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-04
        相关资源
        最近更新 更多