在两个锚点之间居中

时间:2019-05-23 22:07:53

标签: ios swift autolayout anchor

我想在两个锚点之间设置一个centerYAnchor。与此类似:

centeredLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),

但是,我不希望它相对于屏幕居中。我希望它位于屏幕上的其他两个锚点之间。就像我在顶部的工具栏这样:

toolbar.topAnchor.constraint(equalTo: view.topAnchor),

然后我在底部有一个像这样的按钮:

button.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: -20)

有没有一种方法可以使centeredLabel的y约束居中在toolbar的底部锚点和button的顶部锚点之间?

2 个答案:

答案 0 :(得分:4)

  

有没有一种方法可以使centeredLabel的y约束居中在工具栏的底部锚点和按钮的顶部锚点之间?

是的,有。简单的方法是使用透明的间隔视图,其顶部固定在上部锚点上,而底部固定在下部锚点上。现在,您将标签中心固定在间隔视图的中心。

但是,尽管这很简单,但这并不是最好的方式。最好的方法是创建自定义UILayoutGuide而不是透明的间隔视图。不幸的是,这只能在代码中完成,而不能在情节提要中完成(而间隔视图和标签可以完全在情节提要中进行配置)。但是它的优点是不会给渲染树增加额外的视图。

使用按钮作为上视图,使用按钮作为下视图,或多或少是您的情况。标签在它们之间垂直居中:

enter image description here

这是生成这种情况的代码。 b1b2是按钮(它们的创建和放置方式无关紧要):

    let g = UILayoutGuide()
    self.view.addLayoutGuide(g)
    g.topAnchor.constraint(equalTo: b1.bottomAnchor).isActive = true
    g.bottomAnchor.constraint(equalTo: b2.topAnchor).isActive = true
    g.leadingAnchor.constraint(equalTo:b1.leadingAnchor).isActive = true
    g.trailingAnchor.constraint(equalTo:b1.trailingAnchor).isActive = true
    let lab = UILabel()
    lab.text = "Label"
    lab.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(lab)
    lab.leadingAnchor.constraint(equalTo:g.leadingAnchor).isActive = true
    lab.centerYAnchor.constraint(equalTo:g.centerYAnchor).isActive = true

答案 1 :(得分:1)

尽管 @matt 的解决方案有效,但这里有一个更简单的解决方案,它使用自动布局而无需创建 UILayoutGuide。

iOS 10 引入了一种通过 NSLayoutXAxisAnchor.anchorWithOffset(to:)NSLayoutYAxisAnchor.anchorWithOffset(to:) 执行此操作的简单方法。

这里是包装这个逻辑的便捷方法。

用于 X 轴定心

extension NSLayoutXAxisAnchor {
    func constraint(between anchor1: NSLayoutXAxisAnchor, and anchor2: NSLayoutXAxisAnchor) -> NSLayoutConstraint {
        let anchor1Constraint = anchor1.anchorWithOffset(to: self)
        let anchor2Constraint = anchorWithOffset(to: anchor2)
        return anchor1Constraint.constraint(equalTo: anchor2Constraint)
    }
}

用于 Y 轴定心

extension NSLayoutYAxisAnchor {
    func constraint(between anchor1: NSLayoutYAxisAnchor, and anchor2: NSLayoutYAxisAnchor) -> NSLayoutConstraint {
        let anchor1Constraint = anchor1.anchorWithOffset(to: self)
        let anchor2Constraint = anchorWithOffset(to: anchor2)
        return anchor1Constraint.constraint(equalTo: anchor2Constraint)
    }
}

要执行您需要的操作,您可以调用:

centeredLabel.centerYAnchor.constraint(between: toolbar.bottomAnchor, and: button.topAnchor)