视图的底部和右边约束是否定的?

时间:2017-03-24 09:37:21

标签: ios swift uiview nslayoutconstraint

这是一种将子视图固定到UIView实例的方法。请原谅杂乱的代码,我一直在尝试尝试让它发挥作用。

open static func withEmbeddedView(_ view: UIView, andFixedHeight height: CGFloat) -> PMGAlertControllerEmbedComponent {
    let base = PMGAlertControllerEmbedComponent(frame: CGRect.zero)
    base.addSubview(view)
    view.translatesAutoresizingMaskIntoConstraints = false
    base.translatesAutoresizingMaskIntoConstraints = false

    let left = NSLayoutConstraint(item: view, attribute: .left, relatedBy: .equal, toItem: base, attribute: .left, multiplier: 1, constant: 0)
    let right = NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: base, attribute: .right, multiplier: 1, constant: 0)
    let top = NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: base, attribute: .top, multiplier: 1, constant: 0)
    let bottom = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: base, attribute: .bottom, multiplier: 1, constant: 0)
    base.addConstraints([left, right, top, bottom])
    view.addConstraint(NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: height))
    base.leftConstraint = left
    base.rightConstraint = right
    base.topConstraint = top
    base.bottomConstraint = bottom
    base.layoutIfNeeded()
    return base
}

现在这本身就可以正常工作,但是一旦我尝试在其他地方修改这些约束的常量,比如说让它们16添加一些填充,右边和底部的约束就会反过来!因此,16pm的子视图比超级视图要小16磅?顶部和左侧的行为符合预期。

请注意,如果我将顶部和左侧设置为16但将底部和右侧设置为-16,则会产生所需的结果,但我不应该这样做吗?我哪里错了?

非常感谢。

2 个答案:

答案 0 :(得分:4)

约束中的项目顺序很重要。

变化

let bottom = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: base, attribute: .bottom, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: base, attribute: .right, multiplier: 1, constant: 0)

let bottom = NSLayoutConstraint(item: base, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: base, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1, constant: 0)

尝试这样思考:将第二项视为原点。如果值为正,则第一个项目位于第二个项目的右/底方向。如果值为负,则表示方向位于左侧,顶部位于第二个项目。

由于您希望将view放在base内,并且您想要约束中的正值,您需要使用base作为第一项,view作为第二项约束中的项(原点)。因此,当约束的常数为正时,它表示base位于view的右侧/底部。

答案 1 :(得分:0)

听起来很疯狂。现在不能看,但我倾向于在故事板中设置约束,为它们创建出口并改变它们:

self.menuTopConstraint.constant = 64

会将菜单的顶部约束向下移动到导航栏的底部。

将我的主视图向下滑动到菜单的高度:

self.mainViewBottomConstraint.constant = self.indexHeight * -1

欣赏它并没有解决问题。我有更多时间可以看。