使用 Xib 创建的自定义视图在 Interface Builder 中不起作用

Posted

技术标签:

【中文标题】使用 Xib 创建的自定义视图在 Interface Builder 中不起作用【英文标题】:Custom view created with Xib not working in Interface Builder 【发布时间】:2016-11-15 14:53:18 【问题描述】:

我在.Xib 文件的帮助下创建了一个自定义视图。当我以编程方式创建视图并将其添加到我的 ViewController 时,它工作得很好。但是如果我在 Interface Builder 中创建一个 UIView 并将该类设置为我的 CustomView 类并运行它,它就不会显示出来。

这是我的CustomView 类中的代码:

@IBOutlet var view: UIView!

init() 
    super.init(frame:CGRect.zero)
    setup()


override init(frame: CGRect) 
    super.init(frame: frame)
    setup()


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)!
    setup()



func setup() 
    Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)
    view.backgroundColor = UIColor(red: 10.0/255.0, green: 30.0/255.0, blue: 52.0/255.0, alpha: 1.0)
    view.translatesAutoresizingMaskIntoConstraints = false
    view.isUserInteractionEnabled = true



func presentInView(superView:UIView) 

    superView.addSubview(view)

    // Define Constraints
    let height = NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 90.0)
    view.addConstraint(height)

    let topConstraint = NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: superView, attribute: .top, multiplier: 1.0, constant: 0.0)
    let leftConstraint = NSLayoutConstraint(item: view, attribute: .left, relatedBy: .equal, toItem: superView, attribute: .left, multiplier: 1.0, constant: 0.0)
    let rightConstraint = NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: superView, attribute: .right, multiplier: 1.0, constant: 0.0)
    superView.addConstraints([topConstraint,leftConstraint, rightConstraint])

.Xib 文件中,我将Files Owner 的类设置为CustomView,并将IBOutlet view 连接到.Xib 中的主视图。

在我的 ViewController 中,我这样做是为了将 CustomView 添加到其中:

let customView = CustomView()
customView.presentInView(superView: self.view)

当我在 Interface Builder 中添加 UIView 时,它应该像我以编程方式执行它时一样工作。

【问题讨论】:

【参考方案1】:

您是否在界面生成器中为您的 uiview 分配了 CustomView 类。

【讨论】:

是的,我确实像你一样分配了它 你是否从界面构建器中设置了 NSLayoutConstraint 并使它们成为进一步更改的出口 是的,我创建了约束,但我没有让它成为一个出口,因为我不再需要它了。 对,但我可以在你的代码中看到 NSLayout 约束,你可以拍摄你的界面构建的图像,包括约束预览 如果您在界面中设置自定义视图类,那么为什么它会显示这样的出口【参考方案2】:

问题是view 的大小,IBOutlet 我在.Xib 文件中连接到我的视图。当我在代码中创建CustomView 时,我还调用了presentInView 方法,我认为在Interface Builder 中创建时没有必要,因为我在那里设置了约束。但是我忘记了,我在 Interface Builder 中设置的约束是针对类本身的,而不是针对其view 出口的。因此view 需要约束才能将其保存在其父视图中,这不是ViewController.view 而是CustomView。所以我也得写self.addSubview(view)

通过这些更改,它可以工作。这是最终代码:

func setup() 

    Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)
    view.backgroundColor = UIColor(red: 10.0/255.0, green: 30.0/255.0, blue: 52.0/255.0, alpha: 1.0)
    view.translatesAutoresizingMaskIntoConstraints = false
    view.isUserInteractionEnabled = true
    self.addSubview(view)

    let topConstraint = NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0.0)
    let leftConstraint = NSLayoutConstraint(item: view, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0.0)
    let rightConstraint = NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0.0)
    let bottomConstraint = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0.0)
    self.addConstraints([topConstraint,leftConstraint, rightConstraint, bottomConstraint])


不再需要presentInView 方法。

如果其他人遇到这样的问题,希望能有所帮助。

【讨论】:

以上是关于使用 Xib 创建的自定义视图在 Interface Builder 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

iOS:使用 xib 的自定义视图

如何继承具有 .xib 文件的自定义视图

如何响应从 xib 加载的自定义视图中发生的操作?

如何使用 xib 创建自定义视图

来自 XIB 的自定义 UIView 加载具有巨大规模的子视图

由于 nil 子视图,无法使用 Xib 文件创建自定义视图