即使设置了自动布局约束,以编程方式加载的 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 中)。
我有一个带有 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 中)。