UIStackView:将子视图推到边缘("Unlimited" 间距)
UIStackView: push subviews to the edges ("Unlimited" spacing)
我正在使用 UIStackView
定义列表的布局。
我正在尝试实现类似这样的效果:
||Item1---spacing---Item2||
因此,这两个项目被推到 UIStackView
的两侧。
但是,这些项目以 distribution
和 alignment
的所有可能组合组合在一起:
||Item1-Item2-----spacing-----||
我尝试设置一个较大的间距值,即 500。在这种情况下,Item2
就会离开屏幕。
有没有办法把"tie"Item1
和Item2
左右两边UIStackView
,同时允许间距根据屏幕宽度变化?
实现此目的的一种可能方法是在两个视图之间添加一个 'spacing' 视图,并确保视图的拥抱优先级大于间距优先级(当然它们会有有效的固有大小或定义其宽度的约束)。这是我放在一起进行测试的快速游乐场:
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = "Left"
label1.backgroundColor = .red
label1.setContentHuggingPriority(.required, for: .horizontal)
let label2 = UILabel()
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "Right"
label2.backgroundColor = .green
label2.setContentHuggingPriority(.required, for: .horizontal)
let stack = UIStackView(arrangedSubviews: [label1, UIView(), label2])
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fill
stack.axis = .horizontal
view.addSubview(stack)
stack.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
stack.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
stack.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
产生这个:
注意:有趣的是,即使根本没有设置标签的拥抱优先级,我示例中的结果也保持不变(我很想知道为什么顺便说一句,这正在发生。我的猜测是因为它们具有非零的固有内容大小(?)),但决定保留代码以演示其背后的原理。
UIStackView 折叠并将其 intrinsicContentSize 设置为其子视图和间距的总和。
通过向 "stretch" UIStackView 添加一组约束,我设法获得了我想要的效果:
hStack.snp.makeConstraints { (make) in
make.leading.trailing.equalToSuperview()
}
我正在使用 UIStackView
定义列表的布局。
我正在尝试实现类似这样的效果:
||Item1---spacing---Item2||
因此,这两个项目被推到 UIStackView
的两侧。
但是,这些项目以 distribution
和 alignment
的所有可能组合组合在一起:
||Item1-Item2-----spacing-----||
我尝试设置一个较大的间距值,即 500。在这种情况下,Item2
就会离开屏幕。
有没有办法把"tie"Item1
和Item2
左右两边UIStackView
,同时允许间距根据屏幕宽度变化?
实现此目的的一种可能方法是在两个视图之间添加一个 'spacing' 视图,并确保视图的拥抱优先级大于间距优先级(当然它们会有有效的固有大小或定义其宽度的约束)。这是我放在一起进行测试的快速游乐场:
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = "Left"
label1.backgroundColor = .red
label1.setContentHuggingPriority(.required, for: .horizontal)
let label2 = UILabel()
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "Right"
label2.backgroundColor = .green
label2.setContentHuggingPriority(.required, for: .horizontal)
let stack = UIStackView(arrangedSubviews: [label1, UIView(), label2])
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fill
stack.axis = .horizontal
view.addSubview(stack)
stack.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
stack.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
stack.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
产生这个:
注意:有趣的是,即使根本没有设置标签的拥抱优先级,我示例中的结果也保持不变(我很想知道为什么顺便说一句,这正在发生。我的猜测是因为它们具有非零的固有内容大小(?)),但决定保留代码以演示其背后的原理。
UIStackView 折叠并将其 intrinsicContentSize 设置为其子视图和间距的总和。
通过向 "stretch" UIStackView 添加一组约束,我设法获得了我想要的效果:
hStack.snp.makeConstraints { (make) in
make.leading.trailing.equalToSuperview()
}