【问题标题】:Nested UIStackViews inside a UIScrollView: Not filling width of container?UIScrollView 内的嵌套 UIStackViews:不填充容器的宽度?
【发布时间】:2019-09-03 21:17:44
【问题描述】:

我正在尝试使用嵌套在 UIScrollView 中的 UIStackViews 以编程方式创建一个 3x33 的 UIButtons 网格。外部UIStackView 有一个垂直轴,而内部UIStackViews 有水平轴和distribution = .fillEqually

如果我没有封闭的UIScrollView,按钮会正确填充屏幕的宽度。 然而,在滚动视图中,按钮仅占屏幕宽度的一半。

这是一个代码示例。在 IB 中,ViewControllerview 属性已设置为 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
      }
    }
  }

}

【问题讨论】:

    标签: ios swift uiscrollview uikit uistackview


    【解决方案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 个约束来进行测试。
    • 明白。再次感谢。
    猜你喜欢
    • 2019-11-05
    • 2020-02-03
    • 1970-01-01
    • 2015-02-12
    • 2018-06-18
    • 1970-01-01
    • 2015-04-05
    • 2015-12-27
    • 2018-05-26
    相关资源
    最近更新 更多