ios - 如何使用ios swift中的自动布局以编程方式将两个标签并排放置在中心位置?

Posted

技术标签:

【中文标题】ios - 如何使用ios swift中的自动布局以编程方式将两个标签并排放置在中心位置?【英文标题】:How to programmatically place two labels in center side by side with spacing using auto layout in ios swift? 【发布时间】:2019-12-26 01:53:57 【问题描述】:

我对 swift 和 ios 非常陌生,我想以编程方式将两个标签并排放置水平居中。下面是我的代码

let secondLabel : UILabel = 
    let label = UILabel()
    label.text = "1234"
    label.textAlignment = .center
    label.translatesAutoresizingMaskIntoConstraints = false
    label.backgroundColor = UIColor.blue
    return label
()

let thirdLabel : UILabel = 
    let label = UILabel()
    label.text = "5678"
    label.textAlignment = .center
    label.translatesAutoresizingMaskIntoConstraints = false
    label.backgroundColor = UIColor.red
    return label
()

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view.

    setupLayout()


private func setupLayout()
    view.addSubview(secondLabel)
    //secondLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    secondLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    secondLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
    secondLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true

    view.addSubview(thirdLabel)
    //thirdLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    thirdLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    thirdLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
    thirdLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true

    self.view.addConstraint(NSLayoutConstraint(
        item: thirdLabel,
        attribute: .left,
        relatedBy: .equal,
        toItem: secondLabel,
        attribute: .right,
        multiplier: 1.0,
        constant: 10
        ))

但这就是现在的样子

请帮我把标签移到中心

【问题讨论】:

将标签嵌入 UIStackView 并居中 【参考方案1】:

您可以使用 UIStackView 来解决您的问题。请在您的 setupLayout 方法中更新以下代码。

 private func setupLayout()
        let stackview = UIStackView()
        stackview.axis = .horizontal
        stackview.spacing = 10
        stackview.translatesAutoresizingMaskIntoConstraints = false
        stackview.addArrangedSubview(secondLabel)
        secondLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
        secondLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true

        stackview.addArrangedSubview(thirdLabel)
        thirdLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
        thirdLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true

        self.view.addSubview(stackview)
        stackview.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        stackview.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    

输出:-

【讨论】:

如何添加灵活的间距 b/w 两个堆栈视图,即 stackview.spacing = 10。这里我想要灵活的值而不是数字 10 值。【参考方案2】:

虽然UIStackView 是一种方法(很多时候更容易),但有时您想要做你正在尝试的事情。事实是,你就快到了。

private func setupLayout()
    view.addSubview(secondLabel)
    secondLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: -55).isActive = true
    secondLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    secondLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
    secondLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true

    view.addSubview(thirdLabel)
    thirdLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 55).isActive = true
    thirdLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    thirdLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
    thirdLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true


基本上,看起来您有两个 100x100 UILabel,您希望它们相隔 10 个点。所以:

    摆脱最后一个约束。 评论这两个centerXAnchor 约束。这会将两个标签移动到彼此顶部,水平居中。 现在您只需为每个约束添加一个constant 属性。负值向左移动,正值向右移动。由于您的宽度为 100,因此值 50 应该使标签紧挨着每个标签。如果他们之间有 10 分,则为 55。

【讨论】:

【参考方案3】:

UIStackView 将是最佳选择,@manikandan 已正确回答。

但如果你不是UIStackView 的忠实粉丝,你也可以使用UIView 来实现它。多写几行代码就行了。

private func setupLayout() 

    let sampleBackgroundView = UIView()

    sampleBackgroundView.translatesAutoresizingMaskIntoConstraints = false

    sampleBackgroundView.addSubview(secondLabel)
    secondLabel.topAnchor.constraint(equalTo: secondLabel.superview!.topAnchor).isActive = true
    secondLabel.bottomAnchor.constraint(equalTo: secondLabel.superview!.bottomAnchor).isActive = true
    secondLabel.leadingAnchor.constraint(equalTo: secondLabel.superview!.leadingAnchor, constant: 10).isActive = true
    secondLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
    secondLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true

    sampleBackgroundView.addSubview(thirdLabel)

    thirdLabel.topAnchor.constraint(equalTo: secondLabel.superview!.topAnchor).isActive = true
    thirdLabel.bottomAnchor.constraint(equalTo: secondLabel.superview!.bottomAnchor).isActive = true
    thirdLabel.trailingAnchor.constraint(equalTo: secondLabel.superview!.trailingAnchor, constant: 10).isActive = true
    thirdLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
    thirdLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true

    sampleBackgroundView.addConstraint(NSLayoutConstraint(
        item: thirdLabel,
        attribute: .left,
        relatedBy: .equal,
        toItem: secondLabel,
        attribute: .right,
        multiplier: 1.0,
        constant: 10
        ))

    view.addSubview(sampleBackgroundView)
    sampleBackgroundView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    sampleBackgroundView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

请仔细阅读这些解决方案,您将更好地以编程方式实施约束:

How to add constraints programmatically using Swift https://theswiftdev.com/2018/06/14/mastering-ios-auto-layout-anchors-programmatically-from-swift/ https://theswiftdev.com/2017/10/31/ios-auto-layout-tutorial-programmatically/

【讨论】:

【参考方案4】:

您有两种选择(或更多)。

    创建额外的 containerView(UIView) 以 addSubView 您的 2 个标签。然后 centerYAnchor 将该 containerView 锚定到您的 baseView。 使用 UIStackView。将这 2 个标签添加到您的 Horizo​​ntal StackView 和 centerYAnchor 到您的 baseView

简单的解释希望这会有所帮助。

【讨论】:

【参考方案5】:

使用容器视图(UIViewUIStackView)可能是最好的方法,因为它可以让您更轻松地围绕两个标签组构建其他 UI 组件。但是,如果您不需要这种灵活性,或者想避免使用额外的视图,您可以通过布局锚点很好地实现所需的布局:

NSLayoutConstraint.activate([
    // set the size
    secondLabel.widthAnchor.constraint(equalToConstant: 100),
    secondLabel.heightAnchor.constraint(equalToConstant: 100),

    // center vertically in the parent view
    secondLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),

    // align to the left of the parent view center
    secondLabel.rightAnchor.constraint(equalTo: view.centerXAnchor, constant: -5),

    // set the size
    thirdLabel.widthAnchor.constraint(equalToConstant: 100),
    thirdLabel.heightAnchor.constraint(equalToConstant: 100),

    // center vertically in the parent view
    thirdLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),

    // align to the right of the parent view center
    thirdLabel.leftAnchor.constraint(equalTo: view.centerXAnchor, constant: 5)
])

两者之间的间距是通过从 X 中心的偏移量自动实现的。

作为一般说明,出于性能原因,Apple 建议使用activating constraints in batches,使用activate()

此方法的效果与将每个约束的isActive属性设置为true相同。通常,使用这种方法比单独激活每个约束更有效。

【讨论】:

以上是关于ios - 如何使用ios swift中的自动布局以编程方式将两个标签并排放置在中心位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ios swift 中以编程方式创建自动布局等宽约束?

使用 nib 自定义单元格和自动布局滚动跳转(ios 8 swift - UITableview)

iOS/Swift:保持“全局”视图平移不重置其他对象的位置,开启自动布局?

如何使用 Swift 4 在 iOS 9+ 中创建瀑布布局

如何使用ios中的自动布局将三个按钮并排放置在中心并留有间距?

swift 在Xcode 6 GM + iOS 7.1中修复UICollectionViewCell损坏的自动布局约束