Eva*_*man 6 ios nslayoutconstraint swift
我有一个应用程序,它具有动态生成的视图,并且每次加载视图时都可以不同.主视图包含一个设置为主视图边界的ScrollView.然后将子视图动态添加到ScrollView,但这些视图的高度将不同,并且它们可以随时更改高度(例如,用户单击视图的内容并更改).我想使用布局约束来确保每个视图保持与其上方的视图对齐,并使用一些任意填充.见下图:

现在所有填充值都设置为10(顶部,左侧和右侧).我正在使用他们的框架手动设置这些子视图的位置,但如果视图改变大小,这不起作用,所以我想改变它以使用NSLayoutConstraints,但我遇到了一些问题.
作为测试,我像之前一样设置子视图的框架,但后来我添加了约束:
// newView is created and its frame is initialized
self.scrlView?.addSubview(newView)
let constr = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.previousView, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 10)
NSLayoutConstraints.activateConstraints([constr])
newView.translatesAutoResizingMaskIntoConstraints = false
self.previousView = newView
Run Code Online (Sandbox Code Playgroud)
但这些观点无处可见.我究竟做错了什么?所需要的只是确保每个视图的顶部在前一个视图下方对齐,并且无论视图高度如何,它们都保持这种状态.
此外,由于这些视图都被添加到滚动视图中,使用上面的布局约束如何设置滚动视图的正确内容大小?
所以你想要这样的东西:
使用autolayout设置滚动视图的内容大小在技术说明TN2154:UIScrollView和Autolayout中进行了说明.总而言之,autolayout contentSize根据滚动视图及其后代视图之间的约束设置滚动视图.这意味着:
您需要在滚动视图及其后代视图之间创建约束,以便contentSize正确设置滚动视图.
您需要在切片(图片中的彩色视图)和主视图(滚动视图的超级视图)之间创建约束,以正确设置切片的宽度.从磁贴到其封闭滚动视图的约束不能设置磁贴的大小 - 仅contentSize滚动视图的大小.
对于您在代码中创建的任何视图,如果您打算使用约束来控制其大小或位置,您还需要进行设置translatesAutoresizingMaskIntoConstraints = false.否则,自动调整掩码将干扰显式约束的行为.
以下是我制作演示的方法.我使用了一个UIButton子类,当被轻敲时,它会在60到120点之间切换自己的高度:
class HeightTogglingButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
translatesAutoresizingMaskIntoConstraints = false
heightConstraint = heightAnchor.constraint(equalToConstant: 60)
heightConstraint.isActive = true
addTarget(self, action: #selector(HeightTogglingButton.toggle(_:)), for: .touchUpInside)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@IBAction func toggle(_ sender: Any) {
UIView.animate(withDuration: 0.3) {
self.heightConstraint.constant = 180 - self.heightConstraint.constant
self.window?.layoutIfNeeded()
}
}
private(set) var heightConstraint: NSLayoutConstraint!
}
Run Code Online (Sandbox Code Playgroud)
然后我在滚动视图中布置了十个这些按钮.我设置约束来控制每个按钮的宽度,以及每个按钮相对于其他按钮的布局.顶部和底部按钮被约束到滚动视图的顶部和底部,因此它们可以控制scrollView.contentSize.height.所有按钮都被约束到滚动视图的前沿和后沿,因此它们都共同控制scrollView.contentSize.width.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor)])
let margin: CGFloat = 10
var priorAnchor = scrollView.topAnchor
for i in 0 ..< 10 {
let button = HeightTogglingButton()
button.backgroundColor = UIColor(hue: CGFloat(i) / 10, saturation: 0.8, brightness: 0.3, alpha: 1)
button.setTitle("Button \(i)", for: .normal)
scrollView.addSubview(button)
NSLayoutConstraint.activate([
button.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -2 * margin),
button.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: margin),
button.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -margin),
button.topAnchor.constraint(equalTo: priorAnchor, constant: margin)])
priorAnchor = button.bottomAnchor
}
scrollView.bottomAnchor.constraint(equalTo: priorAnchor, constant: margin).isActive = true
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
521 次 |
| 最近记录: |