为什么我的 2D UIViews 没有出现在屏幕上?

Why my 2D UIViews don't appear on screen?

我正在尝试制作包含带边距的 12x7 UIView 的 UIView。我认为最好的方法是制作 7 个垂直堆栈,然后将它们全部添加到一个大的水平堆栈上。我编码了它,但问题是这个水平堆栈根本没有出现在屏幕上(我已经尝试 Xcode 功能来查看图层没有任何内容)。

这是我的代码:

import UIKit

class CalendarView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    
        setupView()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setupView()
    }

    private func setupView() {
        // array to add in future in columnsStackView
        var columnStacks: [UIStackView] = []

        for columns in 1...12 {
            // array to add in future in columnStackView
            var columnViews: [UIView] = []

            for cell in 1...7 {
                let cellView = UIView(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
                cellView.backgroundColor = .orange
                columnViews.append(cellView)
            }

            // create columnStackView and add all 7 views
            let columnStackView = UIStackView(arrangedSubviews: columnViews)
            columnStackView.axis = .vertical
            columnStackView.distribution = .fillEqually
            columnStackView.alignment = .fill
            columnStackView.spacing = 4

            columnStacks.append(columnStackView)
        }

        // create columnsStackView and add those 12 stacks
        let columnsStackView = UIStackView(arrangedSubviews: columnStacks)
        columnsStackView.axis = .horizontal
        columnsStackView.distribution = .fillEqually
        columnsStackView.alignment = .fill
        columnsStackView.spacing = 4
        columnsStackView.translatesAutoresizingMaskIntoConstraints = false

        self.addSubview(columnsStackView)
    }
}

你能帮我吗!!!

两件事...

A UIStackView 在排列其子视图时使用自动布局,所以这一行:

let cellView = UIView(frame: CGRect(x: 0, y: 0, width: 24, height: 24))

将创建一个UIView,但宽度和高度将被忽略。

你需要设置那些有限制的:

for cell in 1...7 {
    let cellView = UIView()
    cellView.backgroundColor = .orange
                
    // we want each "cellView" to be 24x24 points
    cellView.widthAnchor.constraint(equalToConstant: 24.0).isActive = true
    cellView.heightAnchor.constraint(equalTo: cellView.widthAnchor).isActive = true
                
    columnViews.append(cellView)
}

现在,因为我们已经明确设置了“cellViews”的宽度和高度,所以我们可以设置堆栈视图 .distribution = .fill(而不是 .fillEqually)。

接下来,我们必须将“外部”堆栈视图 (columnsStackView) 约束到视图本身:

// constrain the "outer" stack view to self
NSLayoutConstraint.activate([
    columnsStackView.topAnchor.constraint(equalTo: topAnchor),
    columnsStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
    columnsStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
    columnsStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
])

否则,视图将具有 0x0 维。

这是您 class 的修改版本:

class CalendarView: UIView {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupView()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        setupView()
    }
    
    private func setupView() {
        // array to add in future in columnsStackView
        var columnStacks: [UIStackView] = []
        
        for columns in 1...12 {
            // array to add in future in columnStackView
            var columnViews: [UIView] = []
            
            for cell in 1...7 {
                let cellView = UIView()
                cellView.backgroundColor = .orange
                
                // we want each "cellView" to be 24x24 points
                cellView.widthAnchor.constraint(equalToConstant: 24.0).isActive = true
                cellView.heightAnchor.constraint(equalTo: cellView.widthAnchor).isActive = true
                
                columnViews.append(cellView)
            }
            
            // create columnStackView and add all 7 views
            let columnStackView = UIStackView(arrangedSubviews: columnViews)
            columnStackView.axis = .vertical
            columnStackView.distribution = .fill
            columnStackView.alignment = .fill
            columnStackView.spacing = 4
            
            columnStacks.append(columnStackView)
        }
        
        // create columnsStackView and add those 12 stacks
        let columnsStackView = UIStackView(arrangedSubviews: columnStacks)
        columnsStackView.axis = .horizontal
        columnsStackView.distribution = .fill
        columnsStackView.alignment = .fill
        columnsStackView.spacing = 4
        columnsStackView.translatesAutoresizingMaskIntoConstraints = false
        
        self.addSubview(columnsStackView)
        
        // constrain the "outer" stack view to self
        NSLayoutConstraint.activate([
            columnsStackView.topAnchor.constraint(equalTo: topAnchor),
            columnsStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
            columnsStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
            columnsStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
        ])
    }
}

和一个简单的测试控制器来展示如何使用它:

class CalendarTestViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let cv = CalendarView()
        
        cv.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(cv)
        
        // the CalendarView will size itself, so we only need to
        //  provide x and y position constraints
        NSLayoutConstraint.activate([
            cv.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            cv.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        ])
        
        // let's give it a background color so we can see its frame
        cv.backgroundColor = .systemYellow
    }

}

结果: