使用锚的自动布局没有按照我想要的方式布置我的视图?
Posted
技术标签:
【中文标题】使用锚的自动布局没有按照我想要的方式布置我的视图?【英文标题】:Autolayout using anchors not laying out my views the way I intended? 【发布时间】:2017-06-07 06:56:24 【问题描述】:所以我有一个相当简单的单元格视图,我正在尝试自定义它。我有一堆字段和标签,我想如下图所示进行布局
但是我最终使用我设置的约束看起来像这样......
indexLabelBackground(圆圈)
indexLabel(数字)
repsField(REPS左边的0)
repsLabel(REPS 字符串)
dividerLabel(“/”字符串)
weightField(POUNDS 左侧的 0)
weightLabel(磅字符串)
我一遍又一遍地查看我的约束,我找不到任何会让我认为我的约束是错误的,所以我希望一双新的眼睛可以帮助我找出这个令人费解的问题......
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 添加宽度约束。但是,我想避免这种情况,因为在正确的约束条件下,它看起来很笨拙且没有必要。
【问题讨论】:
为什么不使用 Storyboard 呢? 如果您要注释图像以表示代码中的哪个视图引用图像中的哪个视图会更有意义。 这个项目有几个原因,但是是的......我希望以编程方式完成:( 你是对的,对此感到抱歉,进行了编辑 【参考方案1】:问题是您的单元格中有多个元素(字段和标签)可以拉伸以使布局正常工作,而您没有告诉 Auto Layout 哪些元素不要拉伸。
您希望您的标签坚持其固有的内容大小(尽可能大以显示文本,但不要更大)。您可以通过设置高内容拥抱优先级来指定这一点。默认情况下,当您以编程方式创建 UITextField
s 和 UILabel
s 时,它们的内容拥抱优先级为低 (250
)。由于它们都很低,Auto Layout 会以某种未知的顺序拉伸它们以使布局正常工作。
我建议添加这 3 行,为您的 3 个标签将 content 拥抱优先级 设置为 high (750)
:
repsLabel.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal)
dividerLabel.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal)
weightLabel.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal)
这样,您的标签将始终保持其文本所需的大小,然后它们可以锚定您的布局(双关语)。
我什至创建了一个新项目并尝试重新创建此布局 使用故事板使用相同的约束,看起来 不错。
在故事板中,UILabel
s 的默认内容拥抱优先级 (251
) 比UITextFields
(250
) 高,所以它 正常工作。这让我感到震惊,为什么他们选择在以编程方式创建时全部 low (250
)。
【讨论】:
老兄!谢谢你的精彩解释!从来没有弄清楚内容拥抱优先级,但现在我完全明白了 坚如磐石的解释。这节省了我很多时间。 @Badrinath,很高兴它对您有所帮助。请给我点个赞,让其他人知道这个答案很有用。 当然可以,我如何处理同样的问题来垂直自动调整视图?假设我有一个 CreditCard 视图,其中包含以下项目 1. 图像(左)-> 标题 2. 描述 3. 更多详细信息按钮 有时描述会变得更多并隐藏更多详细信息按钮,我可以像下面这样设置self.creditCardDetailView.setContentHuggingPriority(UILayoutPriority.defaultHigh, for: .vertical)
@Badrinath,请将您的问题作为一个新问题发布,其中包含您尝试过的代码的完整详细信息、您得到的结果以及您的期望。在 cmets 中提出新问题会剥夺您从完整 SO 社区获得帮助的权利,并剥夺其他人从 Q 和 A 中受益的权利。以上是关于使用锚的自动布局没有按照我想要的方式布置我的视图?的主要内容,如果未能解决你的问题,请参考以下文章