即使设置了约束,UIView 也会被裁掉
UIView cropped off even though constraints are set
我在 xib 文件中创建了一个自定义视图,我在其中将所有模拟指标设置为 "Inferred"
在我看来,我通过固定左侧和顶部将一个堆栈视图 x 浮动到左侧,通过固定右侧和顶部将堆栈视图浮动到右侧。有点像这样(= 符号表示屏幕边框)
==========
=x y=
= =
= =
= =
= =
==========
我没有对宽度和高度设置任何限制,因为一切都应该是推断出来的。
对应的class我的看法很简单:
class MyView: UIView {
var view:UIView!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
view = UIView.loadFromNibNamed("MyView")
addSubview(view)
}
}
extension UIView {
class func loadFromNibNamed(nibNamed: String, bundle : NSBundle? = nil) -> UIView? {
return UINib(
nibName: nibNamed,
bundle: bundle
).instantiateWithOwner(nil, options: nil)[0] as? UIView
}
}
我在情节提要中使用此视图,方法是将它固定在左侧、右侧、顶部和底部。
.
问题是视图是从笔尖加载的,但宽度不是动态的。我希望视图根据父级的大小调整自身大小。但是,即使我设置了约束,右侧堆栈视图的大约 1/3 被裁掉并且在屏幕上不可见。
我该怎么做才能解决这个问题?
我们需要确定问题所在,所以让我们首先确认堆栈视图正在获取其框架集。在堆栈视图所在的视图控制器中,我们可以覆盖 following methods 并检查堆栈视图的框架。
viewWillLayoyutSubviews()
viewDidLayoutSubviews()
确认框架已设置,我们现在可以查看在故事板中设置的约束。您提供的信息并不清晰,您希望如何将堆栈视图布局在一起,一个在另一个视图之上?他们应该是 side-by-side 吗?
您需要检查约束是否对您想要的布局有效。
3.Confirm 您的视图的大小 类 配置正确。 Apple 在此处有一个名为“Size Classes Design Help”的文档。我相信这是你的问题。您的自定义 class 设置为具有 Any/Any 的大小 class 并且自定义视图的超级视图具有一组不同的大小 classes,例如 Compact/Regular.因此,您的自定义视图 而不是 根据大小 classes 调整其大小,因为它对于任何大小 classes 的组合都设置为相同。尝试为您的自定义 class 配置不同的大小 class 组合,以查看是否存在任何差异 - 例如 Compact/Regular。
如果您希望从 XIB 加载的任何视图具有动态帧大小,则需要将 translatesAutoresizingMaskIntoConstraints
属性 设置为 false
。否则系统会自动创建布局约束,例如固定宽度和固定高度,以防止您的视图调整大小。
此外,在将视图添加到视图层次结构后,您需要在代码中添加一些约束,将其顶部、底部、左侧和右侧边缘固定到其父视图的相应边缘。毕竟,您将 XIB 的内容作为子视图添加到您的自定义视图 MyView
即这两个视图不相同,您需要告诉系统它应该如何定位子视图(您添加的约束故事板仅与您的 MyView
实例相关,与其子视图无关)。添加到您的代码中应该可以解决问题:
class MyView: UIView {
var view:UIView!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
view = UIView.loadFromNibNamed("MyView")
view.translatesAutoresizingMaskIntoConstraints = false
addSubview(view)
// Pin view to all four edges of its superview
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[view]|", options: [], metrics: nil, views: ["view": view]))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: [], metrics: nil, views: ["view": view]))
}
}
旁注:
- 阅读 official documentation 中关于
translatesAutoresizingMaskIntoConstraints
属性 的更详细解释。
- Interface Builder "simulated metrics" 部分中的所有设置仅适用于 Interface Builder 本身。当您在模拟器或真实设备上 运行 应用时,它们不会对您的应用产生任何影响。
我在 xib 文件中创建了一个自定义视图,我在其中将所有模拟指标设置为 "Inferred"
在我看来,我通过固定左侧和顶部将一个堆栈视图 x 浮动到左侧,通过固定右侧和顶部将堆栈视图浮动到右侧。有点像这样(= 符号表示屏幕边框)
==========
=x y=
= =
= =
= =
= =
==========
我没有对宽度和高度设置任何限制,因为一切都应该是推断出来的。
对应的class我的看法很简单:
class MyView: UIView {
var view:UIView!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
view = UIView.loadFromNibNamed("MyView")
addSubview(view)
}
}
extension UIView {
class func loadFromNibNamed(nibNamed: String, bundle : NSBundle? = nil) -> UIView? {
return UINib(
nibName: nibNamed,
bundle: bundle
).instantiateWithOwner(nil, options: nil)[0] as? UIView
}
}
我在情节提要中使用此视图,方法是将它固定在左侧、右侧、顶部和底部。
问题是视图是从笔尖加载的,但宽度不是动态的。我希望视图根据父级的大小调整自身大小。但是,即使我设置了约束,右侧堆栈视图的大约 1/3 被裁掉并且在屏幕上不可见。
我该怎么做才能解决这个问题?
我们需要确定问题所在,所以让我们首先确认堆栈视图正在获取其框架集。在堆栈视图所在的视图控制器中,我们可以覆盖 following methods 并检查堆栈视图的框架。
viewWillLayoyutSubviews() viewDidLayoutSubviews()
确认框架已设置,我们现在可以查看在故事板中设置的约束。您提供的信息并不清晰,您希望如何将堆栈视图布局在一起,一个在另一个视图之上?他们应该是 side-by-side 吗?
您需要检查约束是否对您想要的布局有效。
3.Confirm 您的视图的大小 类 配置正确。 Apple 在此处有一个名为“Size Classes Design Help”的文档。我相信这是你的问题。您的自定义 class 设置为具有 Any/Any 的大小 class 并且自定义视图的超级视图具有一组不同的大小 classes,例如 Compact/Regular.因此,您的自定义视图 而不是 根据大小 classes 调整其大小,因为它对于任何大小 classes 的组合都设置为相同。尝试为您的自定义 class 配置不同的大小 class 组合,以查看是否存在任何差异 - 例如 Compact/Regular。
如果您希望从 XIB 加载的任何视图具有动态帧大小,则需要将 translatesAutoresizingMaskIntoConstraints
属性 设置为 false
。否则系统会自动创建布局约束,例如固定宽度和固定高度,以防止您的视图调整大小。
此外,在将视图添加到视图层次结构后,您需要在代码中添加一些约束,将其顶部、底部、左侧和右侧边缘固定到其父视图的相应边缘。毕竟,您将 XIB 的内容作为子视图添加到您的自定义视图 MyView
即这两个视图不相同,您需要告诉系统它应该如何定位子视图(您添加的约束故事板仅与您的 MyView
实例相关,与其子视图无关)。添加到您的代码中应该可以解决问题:
class MyView: UIView {
var view:UIView!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
view = UIView.loadFromNibNamed("MyView")
view.translatesAutoresizingMaskIntoConstraints = false
addSubview(view)
// Pin view to all four edges of its superview
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[view]|", options: [], metrics: nil, views: ["view": view]))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: [], metrics: nil, views: ["view": view]))
}
}
旁注:
- 阅读 official documentation 中关于
translatesAutoresizingMaskIntoConstraints
属性 的更详细解释。 - Interface Builder "simulated metrics" 部分中的所有设置仅适用于 Interface Builder 本身。当您在模拟器或真实设备上 运行 应用时,它们不会对您的应用产生任何影响。