我想创建始终适合其父视图大小的“GridView”。所以我的想法是这样的:

  • 以垂直堆栈视图为主容器。
  • 在垂直堆栈视图内将是水平堆栈视图的行。
  • 作为填充,我只需要向水平堆栈视图的行添加按钮即可。

  • 因此,有关如何初始化的一般概要如下:
  • 初始化垂直堆栈视图,并将其约束设置为等于其父视图的前导,尾随,宽度和高度锚点。
  • 基于给定的网格(AxB)尺寸,在这些水平行内创建 A 水平堆栈行和 B 按钮。
  • 将每个水平堆栈的约束设置为等于其父视图(主容器堆栈视图)的前导,尾随,宽度和高度。
  • 将每个按钮的autoresizingMask设置为flexibleWidth和flexibleHeight。

  • 到目前为止,这是我目前用于实现“GridView”的逻辑。现在,我遇到的主要问题是,实际上不是水平堆叠视图垂直堆叠,而是最终彼此重叠。

    (1x1)
    Overlap

    如果仅将按钮添加到主容器中,它将垂直堆叠而不会出现问题。

    (1x1)
    Vertical Buttons

    似乎将水平堆栈放在垂直堆栈内会导致此问题。有什么想法和建议吗?我曾经考虑过仅使用表格视图创建网格,但是这个问题让我感到好奇,我真的很想知道为什么会发生这种情况。

    这是我的代码实现:
    func createGrid(x: Int, y: Int, rootView: UIView) {
        //Init stack view.
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.alignment = .fill
        stackView.distribution = .fillEqually
    
    
        for i in (1...x) {
            let hStackView = UIStackView()
            hStackView.axis = .horizontal
            hStackView.alignment = .fill
            hStackView.distribution = .fillEqually
    
            for _ in (1...y) {
                let button = WordBoxView()
                button.setTitle("\(i)", for: .normal)
                hStackView.addArrangedSubview(button)
            }
    
            let button = WordBoxView()
            button.setTitle("\(i)", for:.normal)
            hStackView.addArrangedSubview(button)
    
            //Add horizontal row stack to vertical parent stack.
            stackView.addSubview(hStackView)
            fitParentLayout(hStackView, parentView: stackView)
        }
    
        rootView.addSubview(stackView)
    
        //setup stack view bounds
        stackView.translatesAutoresizingMaskIntoConstraints = false
        fitParentLayout(stackView, parentView: rootView)
    }
    
    func fitParentLayout(_ child: UIView, parentView: UIView) {
    
        child.translatesAutoresizingMaskIntoConstraints = false
    
        NSLayoutConstraint.activate([
            parentView.leadingAnchor.constraint(equalTo: child.leadingAnchor),
            parentView.trailingAnchor.constraint(equalTo: child.trailingAnchor),
            parentView.widthAnchor.constraint(equalTo: child.widthAnchor),
            parentView.heightAnchor.constraint(equalTo: child.heightAnchor)])
    }
    

    最佳答案

    我在您的代码中发现2个问题:

  • 您已经添加了leading, trailing, widthheight约束,但是它不能确定视图的y起源。因此,分配top。 (前导和尾随将自动确定宽度,因此无需给出宽度约束)
  • 您只需要对外部UIStackView施加约束,内部堆栈视图将根据外部堆栈视图的属性自动获取帧。

  • 将您的代码更新为:
    func createGrid(x: Int, y: Int, rootView: UIView) {
        //Init stack view.
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.alignment = .fill
        stackView.distribution = .fillEqually
        stackView.spacing = 10
    
        for i in 1...x {
            let hStackView = UIStackView()
            hStackView.axis = .horizontal
            hStackView.alignment = .fill
            hStackView.distribution = .fillEqually
            hStackView.spacing = 10
    
            for _ in 1...y {
                let button = UIButton()
                button.backgroundColor = .red
                button.setTitle("\(i)", for: .normal)
                hStackView.addArrangedSubview(button)
            }
    
            //Add horizontal row stack to vertical parent stack.
            stackView.addArrangedSubview(hStackView)
        }
    
        rootView.addSubview(stackView)
    
        //setup stack view bounds
        fitParentLayout(stackView, parentView: rootView)
    }
    
    
    func fitParentLayout(_ child: UIView, parentView: UIView) {
        child.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            parentView.leadingAnchor.constraint(equalTo: child.leadingAnchor),
            parentView.trailingAnchor.constraint(equalTo: child.trailingAnchor),
            parentView.topAnchor.constraint(equalTo: child.topAnchor),
            parentView.heightAnchor.constraint(equalTo: child.heightAnchor)])
    }
    

    关于ios - 试图以编程方式使用嵌套堆栈 View 创建网格,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49885802/

    10-10 23:14
    查看更多