水平 UIStackView - 固定中心项目的大小并拉伸其他项目
Horizontal UIStackView - fix center item's size and stretch other items
我正在尝试实现这样的布局:
基本上,我需要 or
标签保持在中间并占据固定的宽度,并且线条向屏幕边缘延伸。
这是我在 XIB 中所做的:
- 创建了水平 UIStackview,
center
对齐。
- 设置stackview的高度约束为
20
,分布为fill
。
- 添加了两个
UIView
元素(用于灰线),高度限制设置为 5。
- 在上面的两个
UIView
元素之间添加了一个 UILabel。
- 添加了更多约束:
- 左 UIView 以
0
从超级视图开始,以 5
尾随到中间标签
- 右 UIView 从中间标签
4
开始,然后 0
到超级视图。
在 Interface builder 上看起来不错,但在不同的屏幕尺寸和横向上,我发现中间的“or
”标签可以拉伸并踢开左右 UIView 以弥补可用 space,这似乎是正确的:
如果我在中间标签上设置 20
的宽度约束,右侧的 UIView 会像这样不均匀地伸展:
我知道元素的 CHP 在某种程度上很重要,我什至尝试过这样设置 CHP:
中间标签的CHP为251
左右UIViews的CHP为250
这仍然给我留下了右 UIView 不均匀拉伸的问题。
我做错了什么?非常感谢见解!
非常感谢!
不要设置任何前导或尾随约束...
将 "right view" 宽度约束设置为 "left view" 宽度,并为堆栈视图提供 spacing
值 4 或 5。
故事板:
纵向:
横向:
您需要在 UIStackView
上设置 widthConstraint
并生成 leftView.widthAnchor = rightView.widthAnchor
。或者,您可以在 UIStackView 上设置 leading
和 trailing
约束,然后设置 leftView.widthAnchor = rightView.widthAnchor
.
下面是您可以在 Playgrounds 中试用的示例代码
let leftView = UIView()
leftView.translatesAutoresizingMaskIntoConstraints = false
leftView.backgroundColor = .lightGray
let rightView = UIView()
rightView.translatesAutoresizingMaskIntoConstraints = false
rightView.backgroundColor = .lightGray
let orLabel = UILabel()
orLabel.translatesAutoresizingMaskIntoConstraints = false
orLabel.textColor = .black
orLabel.text = "or"
let stackView = UIStackView(arrangedSubviews: [leftView, orLabel, rightView])
stackView.alignment = .center
stackView.distribution = .fill
stackView.axis = .horizontal
stackView.spacing = 5
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
stackView.heightAnchor.constraint(equalToConstant: 20).isActive = true
stackView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
leftView.heightAnchor.constraint(equalToConstant: 5).isActive = true
rightView.heightAnchor.constraint(equalToConstant: 5).isActive = true
leftView.widthAnchor.constraint(equalTo: rightView.widthAnchor).isActive = true
我正在尝试实现这样的布局:
基本上,我需要 or
标签保持在中间并占据固定的宽度,并且线条向屏幕边缘延伸。
这是我在 XIB 中所做的:
- 创建了水平 UIStackview,
center
对齐。 - 设置stackview的高度约束为
20
,分布为fill
。 - 添加了两个
UIView
元素(用于灰线),高度限制设置为 5。 - 在上面的两个
UIView
元素之间添加了一个 UILabel。 - 添加了更多约束:
- 左 UIView 以
0
从超级视图开始,以5
尾随到中间标签 - 右 UIView 从中间标签
4
开始,然后0
到超级视图。
在 Interface builder 上看起来不错,但在不同的屏幕尺寸和横向上,我发现中间的“or
”标签可以拉伸并踢开左右 UIView 以弥补可用 space,这似乎是正确的:
如果我在中间标签上设置 20
的宽度约束,右侧的 UIView 会像这样不均匀地伸展:
我知道元素的 CHP 在某种程度上很重要,我什至尝试过这样设置 CHP:
中间标签的CHP为251
左右UIViews的CHP为250
这仍然给我留下了右 UIView 不均匀拉伸的问题。
我做错了什么?非常感谢见解! 非常感谢!
不要设置任何前导或尾随约束...
将 "right view" 宽度约束设置为 "left view" 宽度,并为堆栈视图提供 spacing
值 4 或 5。
故事板:
纵向:
横向:
您需要在 UIStackView
上设置 widthConstraint
并生成 leftView.widthAnchor = rightView.widthAnchor
。或者,您可以在 UIStackView 上设置 leading
和 trailing
约束,然后设置 leftView.widthAnchor = rightView.widthAnchor
.
下面是您可以在 Playgrounds 中试用的示例代码
let leftView = UIView()
leftView.translatesAutoresizingMaskIntoConstraints = false
leftView.backgroundColor = .lightGray
let rightView = UIView()
rightView.translatesAutoresizingMaskIntoConstraints = false
rightView.backgroundColor = .lightGray
let orLabel = UILabel()
orLabel.translatesAutoresizingMaskIntoConstraints = false
orLabel.textColor = .black
orLabel.text = "or"
let stackView = UIStackView(arrangedSubviews: [leftView, orLabel, rightView])
stackView.alignment = .center
stackView.distribution = .fill
stackView.axis = .horizontal
stackView.spacing = 5
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
stackView.heightAnchor.constraint(equalToConstant: 20).isActive = true
stackView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
leftView.heightAnchor.constraint(equalToConstant: 5).isActive = true
rightView.heightAnchor.constraint(equalToConstant: 5).isActive = true
leftView.widthAnchor.constraint(equalTo: rightView.widthAnchor).isActive = true