为什么自定义CalendarView中的UIStackView和子UIView无法在屏幕显示?
问题排查及修复方案
核心问题原因
- 你给最外层的横向
columnsStackView设置了translatesAutoresizingMaskIntoConstraints = false,但没有添加任何约束来定义它的位置和尺寸,Auto Layout 下没有确定布局的视图会默认被渲染在零大小区域,自然无法显示也找不到层级。 - 所有嵌套的子StackView和内部的cellView没有明确的尺寸约束,放在StackView中时虽然你设置了
fillEqually,但外层容器没有基准尺寸的情况下布局计算会失败。
修复代码
import UIKit class CalendarView: UIView { // 配置参数,方便后续调整 private let cellSize: CGFloat = 24 private let spacing: CGFloat = 4 private let columnCount = 12 private let rowCount = 7 override init(frame: CGRect) { super.init(frame: frame) setupView() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setupView() } private func setupView() { var columnStacks: [UIStackView] = [] for _ in 1...columnCount { var columnViews: [UIView] = [] for _ in 1...rowCount { let cellView = UIView() cellView.backgroundColor = .orange // 给cell加固定宽高约束,确保尺寸统一 cellView.widthAnchor.constraint(equalToConstant: cellSize).isActive = true cellView.heightAnchor.constraint(equalToConstant: cellSize).isActive = true columnViews.append(cellView) } let columnStackView = UIStackView(arrangedSubviews: columnViews) columnStackView.axis = .vertical columnStackView.distribution = .fillEqually columnStackView.alignment = .fill columnStackView.spacing = spacing columnStacks.append(columnStackView) } let columnsStackView = UIStackView(arrangedSubviews: columnStacks) columnsStackView.axis = .horizontal columnsStackView.distribution = .fillEqually columnsStackView.alignment = .fill columnsStackView.spacing = spacing columnsStackView.translatesAutoresizingMaskIntoConstraints = false self.addSubview(columnsStackView) // 给外层StackView添加和父视图的边距约束,撑满整个CalendarView NSLayoutConstraint.activate([ columnsStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor), columnsStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor), columnsStackView.topAnchor.constraint(equalTo: self.topAnchor), columnsStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) // 可选:给CalendarView添加固有内容尺寸,使用的时候不需要额外给宽高约束 let totalWidth = CGFloat(columnCount) * cellSize + CGFloat(columnCount - 1) * spacing let totalHeight = CGFloat(rowCount) * cellSize + CGFloat(rowCount - 1) * spacing self.invalidateIntrinsicContentSize() self.intrinsicContentSize = CGSize(width: totalWidth, height: totalHeight) } }
使用说明
修复后使用CalendarView时,要么给它设置明确的frame,要么添加宽高约束,也可以直接用它的固有尺寸配合自适配布局。
内容的提问来源于stack exchange,提问作者rrakhlin
相关产品推荐
相关产品推荐

