布局水平锚点的问题 - Swift 3

时间:2017-03-13 15:24:08

标签: ios swift xcode swift3

任何人都可以提供有关我的代码无效的原因吗?

我正在尝试在图片中的两个视图之间添加水平间距(红色和黑色)但由于某种原因我一直收到该错误,我不确定如何修复它。

我假设其他约束工作正常,因为我没有看到任何问题,也没有在模拟或控制台中。

enter image description here

用户请求的代码:https://gist.github.com/sungkim23/66ecd9ce71d0480f083bcd05caf0a58c

import UIKit

class BuyButton: UIView {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        //MARK: - View
        backgroundColor = UIColor(red: 180/255, green: 35/255, blue: 115/255, alpha: 1)
        layer.cornerRadius = 3

        //MARK: - Price View
        let priceView = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: bounds.size.height))
        priceView.backgroundColor = UIColor.black
        addSubview(priceView)

        //MARK: - Purchase View
        let purchaseView = UIView(frame: CGRect(x: 80, y: 0, width: bounds.size.width - 80, height: bounds.size.height))
        purchaseView.backgroundColor = UIColor.red
        addSubview(purchaseView)

        //MARK: - Price Label
        let priceLabel = UILabel(frame: CGRect.zero)
        priceLabel.text = "$ 50.00"
        priceLabel.textAlignment = .center
        priceLabel.backgroundColor = .red
        priceLabel.translatesAutoresizingMaskIntoConstraints = false
        priceView.addSubview(priceLabel)

        //MARK: - Purchase Label
        let purchaseLabel = UILabel(frame: CGRect.zero)
        purchaseLabel.text = "Purchase"
        purchaseLabel.textAlignment = .center
        purchaseLabel.backgroundColor = .green
        purchaseLabel.translatesAutoresizingMaskIntoConstraints = false
        purchaseView.addSubview(purchaseLabel)

        //MARK: - View Constraints
        priceView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        priceView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        priceView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

        purchaseView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        purchaseView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        purchaseView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

        priceView.centerXAnchor.constraint(equalTo: purchaseView.centerXAnchor).isActive = true

        //MARK: - Label Constraints
        priceLabel.centerXAnchor.constraint(equalTo: priceView.centerXAnchor).isActive = true
        priceLabel.centerYAnchor.constraint(equalTo: priceView.centerYAnchor).isActive = true
        purchaseLabel.centerXAnchor.constraint(equalTo: purchaseView.centerXAnchor).isActive = true
        purchaseLabel.centerYAnchor.constraint(equalTo: purchaseView.centerYAnchor).isActive = true

        //MARK: - Constraint priorities

    }
}

更新1 - 添加了要求提问的错误

2017-03-13 11:02:38.440892 ButtonTest[20954:1645749] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
"<NSAutoresizingMaskLayoutConstraint:0x60000009a400 h=--& v=--& UIView:0x7fe55be017b0.midX == 40   (active)>",
"<NSAutoresizingMaskLayoutConstraint:0x600000099ff0 h=--& v=--& UIView:0x7fe55bc09310.midX == 232   (active)>",
"<NSLayoutConstraint:0x600000099c30 UIView:0x7fe55be017b0.centerX == UIView:0x7fe55bc09310.centerX   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600000099c30 UIView:0x7fe55be017b0.centerX ==    UIView:0x7fe55bc09310.centerX   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to   catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

更新2 - tl; dr

使用
yourView.leadingAnchor.constraint(equalTo:yourOtherView.trailingAnchor).isActive = true

而不是

yourView.centerXAnchor.constraint(equalTo:yourOtherView.centerXAnchor).isActive = true

2 个答案:

答案 0 :(得分:4)

好的,从你对Matt的问题的评论。你仍然没有考虑约束:D

您不需要考虑bounds.size.width - 80frame的{​​{1}}。这不是一个rect的事情。

为了考虑AutoLayout中的布局,您需要描述应用程序的布局。

这就是我想你想要的......

  • 价格视图的宽度应固定为80。
  • 价格视图的前沿,上边和下边缘将分别为超级视图的前沿,上边和下边缘留出0个空格。
  • 购买视图的前沿应该有0个空格到价格视图的后端。
  • 购买视图的尾部,顶部和底部边缘应为超级视图的尾部,顶部和底部边缘留出0个空格。

从此列表中,价格视图和购买视图只有一种可能的布局。任何其他布局都会与约束相矛盾。另外,我没有添加任何我不需要的东西。例如,遵循这些说明,两个视图的AutoLayout将是相同的。我不需要明确地添加它。

所以现在你有这个非常简单的描述......只需添加它。

centerYAnchor

应该是它(对于价格视图和购买视图)。

使用AutoLayout时,请勿尝试使任务过于复杂。 AutoLayout为您完成了很多工作。

编辑 - UIStackView

根据@ abizern对你问题的评论。你应该看看// set the width of price view priceView.widthAnchor.constraint(equalToConstant: 80).isActive = true // now add the other edges to super view priceView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true priceView.topAnchor.constraint(equalTo: topAnchor).isActive = true priceView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true // set the spacing between price view and purchase view purchaseView.leadingAnchor.constraint(equalTo: priceView.trailingAnchor).isActive = true // add the other edges to the super view purchaseView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true purchaseView.topAnchor.constraint(equalTo: topAnchor).isActive = true purchaseView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true 。它消除了很多这种痛苦,并使使用自动布局的布局更容易。

答案 1 :(得分:2)

问题1:你从未说过

priceView.translatesAutoresizingMaskIntoConstraints = false

问题2:你从未说过

purchaseView.translatesAutoresizingMaskIntoConstraints = false

问题3:您需要priceViewpurchaseView上的一整套约束。

换句话说,你不能像这样混合和匹配,对某些视图使用frame,对其他视图使用自动布局。一旦视图涉及自动布局,自动布局中的完全,必须完全按自动布局定位和调整大小。

所以,如果你修复问题1和问题2,没有更多的控制台错误 - 但随后你会发现视图的位置/大小变得疯狂,因为你已经从超定的布局变为欠定的布局。现在您需要填写缺少的约束来确定布局。特别是:

  • 需要确定黑色视图的宽度(priceView)。

  • 需要确定红色视图的宽度和x位置(purchaseView)。

相关问题