我想创建始终符合其父视图大小的“GridView”。所以我的想法是:
所以关于它如何被初始化的一般纲要是这样的:
这是我目前用于初始化“GridView”的逻辑,我正在使用它进行实现。现在我遇到的主要问题是,而不是垂直堆叠的水平堆栈视图,它实际上最终会重叠在彼此之上。
(1×1) Overlap
如果我将按钮只是添加到主容器中,它将垂直堆叠而不会出现问题。
(1×1) 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)])
}
答案 0 :(得分:2)
我在您的代码中发现了2个问题:
您已添加
leading, trailing, width
和height
限制,但不会确定您的观看次数。所以指定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)])
}
答案 1 :(得分:1)
你说
将每个水平堆栈的约束设置为等于其父视图(主容器堆栈视图)的前导,尾随,宽度和高度。
您不希望行的高度(水平堆栈视图)等于主容器堆栈视图的高度。设置高度限制可能是造成困境的原因。
删除此约束:
parentView.heightAnchor.constraint(equalTo: child.heightAnchor)
您也不需要父/子宽度约束,但那个是无害的。
答案 2 :(得分:1)
几个"呐喊"错误...
在for i in (1...x)
循环结束时:
//Add horizontal row stack to vertical parent stack.
stackView.addSubview(hStackView)
应该是:
//Add horizontal row stack to vertical parent stack.
stackView.addArrangedSubview(hStackView)
并且,您不需要(也不应该)以下行
fitParentLayout(hStackView, parentView: stackView)
因为您正在使用垂直堆栈视图的.alignment
和.distribution
来控制子水平堆栈视图的大小/位置。
并且,您的fitParentLayout()
已交换视图。它应该是:
func fitParentLayout(_ child:UIView, parentView:UIView)
{
child.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
child.leadingAnchor.constraint(equalTo: parentView.leadingAnchor),
child.trailingAnchor.constraint(equalTo: parentView.trailingAnchor),
child.topAnchor.constraint(equalTo: parentView.topAnchor),
child.bottomAnchor.constraint(equalTo: parentView.bottomAnchor)])
}
应该这样做。