Autolayout使用锚点没有像我预期的那样阐述我的观点?

时间:2017-06-07 06:56:25

标签: ios swift swift3 autolayout nslayoutconstraint

所以我有一个相当简单的单元格视图,我正在尝试自定义。我有一堆字段和标签,我想布局如下图所示

enter image description here

然而,我最终使用我设置的约束看起来像这样......

indexLabelBackground (圈子)

indexLabel (数字)

repsField (REPS左侧为0)

repsLabel (REPS字符串)

dividerLabel (" /"字符串)

weightField (POUNDS左侧的0)

weightLabel (POUNDS字符串)

enter image description here

我一遍又一遍地看着我的约束,我找不到任何会让我觉得我的约束是错误的,所以我希望一双新眼睛可以帮助我找出这个令人费解的问题......

P.S。我甚至创建了一个新项目,并尝试使用故事板重新创建此布局,使用相同的约束看起来很好。

private func setupViews() {
    addSubview(indexLabelBackground)
    indexLabelBackground.addSubview(indexLabel)
    addSubview(repsField)
    addSubview(repsLabel)
    addSubview(dividerLabel)
    addSubview(weightField)
    addSubview(weightLabel)

    indexLabelBackground.leftAnchor.constraint(equalTo: leftAnchor, constant: 24).isActive = true
    indexLabelBackground.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    indexLabelBackground.heightAnchor.constraint(equalToConstant: 24).isActive = true
    indexLabelBackground.widthAnchor.constraint(equalToConstant: 24).isActive = true

    indexLabel.centerXAnchor.constraint(equalTo: indexLabelBackground.centerXAnchor).isActive = true
    indexLabel.centerYAnchor.constraint(equalTo: indexLabelBackground.centerYAnchor).isActive = true

    repsField.leftAnchor.constraint(equalTo: indexLabelBackground.rightAnchor, constant: 8).isActive = true
    repsField.rightAnchor.constraint(equalTo: repsLabel.leftAnchor, constant: -8).isActive = true
    repsField.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true

    repsLabel.rightAnchor.constraint(equalTo: dividerLabel.leftAnchor, constant: -16).isActive = true
    repsLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true

    dividerLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
    dividerLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true

    weightField.leftAnchor.constraint(equalTo: dividerLabel.rightAnchor, constant: 16).isActive = true
    weightField.rightAnchor.constraint(equalTo: weightLabel.leftAnchor, constant: -8).isActive = true
    weightField.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true

    weightLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -16).isActive = true
    weightLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
//  weightLabel.widthAnchor.constraint(equalToConstant: 60).isActive = true //note this fixes the problem but forces my label to be a fixed width
    }

需要注意的是,如果你看一下最后一行,这可以是"修复"以一种hacky方式,例如向weightLabel添加宽度约束。但是,我希望避免这种情况,因为它似乎很容易被正确的约束所困扰。

1 个答案:

答案 0 :(得分:2)

问题在于您的单元格中有多个元素(字段和标签)可以拉伸以使布局正常工作,并且您还没有告诉自动布局哪些不是拉伸。

您希望您的标签坚持其内在内容大小(尽可能大到显示文字,但不能更大)。您可以通过设置高内容拥抱优先级来指定此项。默认情况下,当您以编程方式创建UITextFieldUILabel时,其内容拥抱优先级 250)。由于它们都很低,自动布局会以某种未知顺序拉伸它们以使布局有效。

我建议添加这3行,为您的3个标签设置内容拥抱优先级 (750)

repsLabel.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal)
dividerLabel.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal)
weightLabel.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal)

这样,您的标签将始终是保存文字所需的尺寸,然后他们可以锚定您的布局(双关语)。

  

我甚至创建了一个新项目并尝试重新创建此布局   使用故事板使用看似相似的约束   好。

Storyboard 中,UILabel的默认内容拥抱优先级251)高于UITextFields({{ 1}}),所以只是工作。它打败了我为什么他们选择在以编程方式创建 low 250)时给他们。