UIScrollView 内的嵌套 UIStackViews:不填充容器的宽度?
Posted
技术标签:
【中文标题】UIScrollView 内的嵌套 UIStackViews:不填充容器的宽度?【英文标题】:Nested UIStackViews inside a UIScrollView: Not filling width of container? 【发布时间】:2019-09-03 21:17:44 【问题描述】:我正在尝试使用嵌套在 UIScrollView
中的 UIStackView
s 以编程方式创建一个 3x33 的 UIButton
s 网格。外部UIStackView
有一个垂直轴,而内部UIStackView
s 有水平轴和distribution = .fillEqually
。
如果我没有封闭的UIScrollView
,按钮会正确填充屏幕的宽度。 然而,在滚动视图中,按钮仅占屏幕宽度的一半。
这是一个代码示例。在 IB 中,ViewController
的 view
属性已设置为 UIScrollView
实例。
class ViewController: UIViewController
var stackView: UIStackView!
override func viewDidLoad()
super.viewDidLoad()
title = "No Filling :("
stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 5
view.addSubview(stackView)
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[stackView]-|", options: .alignAllCenterX, metrics: nil, views: ["stackView": stackView!]))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[stackView]|", options: .alignAllCenterY, metrics: nil, views: ["stackView": stackView!]))
for _ in 1...33
let hView = UIStackView()
hView.translatesAutoresizingMaskIntoConstraints = false
hView.axis = .horizontal
hView.distribution = .fillEqually
hView.spacing = 5
stackView.addArrangedSubview(hView)
stackView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[hView]|", options: .alignAllCenterX, metrics: nil, views: ["hView": hView]))
for i in 1...3
let button = UIButton(type: .system)
button.setTitle("Button \(i)", for: .normal)
hView.addArrangedSubview(button)
button.layer.borderWidth = 1
button.layer.cornerRadius = 7
【问题讨论】:
【参考方案1】:您希望 scrollView 的内容宽度与 scrollView 本身的宽度相同,以便它填满屏幕并垂直滚动。
为此,您需要确定滚动视图内容的宽度。现在,它的宽度来自三个按钮的固有尺寸。
你需要添加一个约束,明确让scrollView的内容(stackView+左右偏移)等于scrollView的宽度:
view.addConstraints(NSLayoutConstraint.constraints(
withVisualFormat: "H:|-20-[stackView]-20-|", options: .alignAllCenterX,
metrics: nil, views: ["stackView": stackView!]))
view.addConstraints(NSLayoutConstraint.constraints(
withVisualFormat: "V:|[stackView]|", options: .alignAllCenterY,
metrics: nil, views: ["stackView": stackView!]))
stackView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -40).isActive = true
注意:调整constant
-40
是左右偏移的总和(20
各)。为了让 scrollView 不水平滚动:stackView.width + 20 + 20 == scrollView.width
,或者等效地,stackView.width == scrollView.width - 40
,这是约束指定的。
【讨论】:
再想一想,我意识到我一定是误解了NSLayoutConstraint.constraints(withVisualFormat:options:metrics:views)
。我之前的理解是视觉格式H:|-[stackView]-|
会处理它的前导、尾随和宽度锚点,并根据超级视图自己的锚点(在本例中为滚动视图)设置它们。为什么不设置宽度锚点?
这只会创建前导和尾随约束。
您可以通过将.count
添加到该命令并观察到仅创建了2 个约束来进行测试。
明白。再次感谢。以上是关于UIScrollView 内的嵌套 UIStackViews:不填充容器的宽度?的主要内容,如果未能解决你的问题,请参考以下文章
UIButton 没有响应嵌套在另一个 UIScrollView 中的 UIScrollView 中的触摸
UIScrollView 内的 UIScrollView 时滚动
分页 UIScrollView 内的 UIScrollView