即使设置了自动布局约束,以编程方式加载的 Nib 也不会填充父容器

Programmatically Loaded Nib doesn't fill parent container even when Autolayout constraints are set

我有一个带有 init 方法的笔尖:

override init() {
    super.init();
    self.view = NSBundle.mainBundle().loadNibNamed("myNib", owner: self, options: nil).first as? UIView;
    self.addSubview(self.view);
}

在 UITableView 单元格中,我像这样加载笔尖:

override func awakeFromNib() {
    self.myInnerNib = myNib();
    self.nibContainerView?.addSubview(self.myInnerNib!);
}

笔尖是自由形式的,其约束设置为填充父视图的容器。但是,当我在更大的设备上加载它时,很明显视图没有填充它的父级。

加载 nib 时,您会收到一个视图数组,通常您会采用顶层视图并将其添加为子视图。容器和我的笔尖之间是否有另一个视图阻止笔尖正确调整大小?

编辑

我用 frame 方法覆盖了我的 init,我强制 nib 中的子视图设置它们的框架,而不是让它们被隐式推断

override init(frame: CGRect) {
    super.init(frame: frame);
    self.view = NSBundle.mainBundle().loadNibNamed("DayLineGraphView", owner: self, options: nil).first as? UIView;
    self.view.frame = frame; <- problem
    self.innerView.frame = frame;  <-problem
    self.addSubview(self.view);

    setupGraph()

}

您已正确识别有问题的行:

self.view.frame = frame; <- problem
self.innerView.frame = frame;  <-problem

您在这里所做的是设置视图框架和将 innerView 框架设置为相同的东西。这是错误的原因是 innerView 上的原点很可能不正确(并非总是如此,但通常如此)。如果 innerView 要填充 view,您必须确保原点是 {0, 0}。一种简单的方法是使用视图的 bound property:

self.view.frame = frame;
self.innerView.frame = self.view.bounds;

这应该可以解决您的问题。

关于约束的另一个说明。在这种情况下,"container" 视图可能在 IB 中具有适当的约束,但您正在向它添加一个子视图,它需要自己的约束。因此 "container" 视图需要为 "subview" 建立约束。由于您是以编程方式添加子视图,因此也必须以编程方式设置约束。您可能怀疑这是不正确的原因是因为方便的 translatesAutoresizingMaskIntoConstraints 布尔值。这将允许 iOS 对其认为约束应该是什么做出有根据的猜测。由于您将大小设置为相等,因此它设置了约束以填充父级...但约束仍在运行时建立(即不在 IB 中)。