在两个锚点之间居中

Centering between two anchors

我想在两个锚点之间设置一个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 的顶部锚点之间?

is there a way I can center centeredLabel's y constraint to be right between the bottomanchor of toolbar and the top anchor of button?

是的,有。简单的方法是使用透明间隔视图,其顶部锚定到上锚点,底部锚定到下锚点。现在你 center-anchor 你的标签到间隔视图的中心。

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

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

这是产生这种情况的代码。 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

虽然 的解决方案有效,但这里有一个更简单的解决方案,它使用自动布局而不需要创建 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)