如何控制嵌套在另一个堆栈视图中的UIStackViews的相对宽度?

时间:2015-11-11 16:48:27

标签: ios uistackview stackview

我有一个相当困难的布局设计,在iOS中使用嵌套堆栈视图可能会更容易。但是,我在控制嵌套在其他堆栈中的堆栈的大小或分布时遇到问题。例如,如果我将“分布”设置为“适合”,则布局的一部分看起来很好: enter image description here

但是,我真正想要的是照片和容器大约是文本字段堆栈宽度的1/3。如果我按比例将分布设置为适合,则堆叠图像(不会改变大小)和容器展开,并将文本压在显示器的侧面。我读到的所有内容都建议降低内容压缩阻力优先级。我在图像,容器和堆栈视图本身上尝试了这个,但它没有做太多。

有人可以指出我正确的方向来控制嵌套在其他堆栈中的堆栈的相对宽度吗?

3 个答案:

答案 0 :(得分:1)

我希望可能有更好的答案,但我发现的唯一有效的方法是将图像放入视图并将其固定到视图的边缘。然后可以使用约束来控制视图的大小。

如果有人有更好的方法,他们仍然可以回答这个更详细的问题的一部分: https://stackoverflow.com/questions/33875801/how-to-position-and-size-images-and-their-frames-in-nested-stack-views-in-ib-w

答案 1 :(得分:1)

回答你的问题:有人可以指出我正确的方向来控制嵌套在其他堆栈中的堆栈的相对宽度吗?  ...

问题在于,顶级 UIStackView在确定如何将多余的空间/壁球拼凑在一起时,要求所有子视图的intrinsicContentSize每个子视图的返回intrinsicContentSize及其contentHuggingPriority / contentCompressionResistance。遗憾的是,UIStackView本身 - 即您的嵌套 UIStackView - 并未返回对其自身intrinsicContentSize有用的任何内容(尽管它有自己的子视图,但这样做) 。因此,顶层的UIStackView只是向前推进,并且就像嵌套的一个并不关心那样,这就是为什么你的嵌套UIStackView的结尾比你想要的更宽。

我通过使用一个简单的UIStackView子类为嵌套的子类运气好运,它根据自己内容的宽度(对于垂直轴)或高度(对于a)返回一个有用的intrinsicContentSize水平轴),如下:

@implementation NestedStackView
- (CGSize)intrinsicContentSize
{
    CGSize size = [super intrinsicContentSize]; // returns {UIViewNoIntrinsicMetric,UIViewNoIntrinsicMetric}

    for (UIView *view in self.arrangedSubviews)
        if (!view.hidden) { // UIStackView ignores hidden subviews when doing its layout; so should we...
            if (self.axis == UILayoutConstraintAxisVertical) {
                size.width = MAX(view.intrinsicContentSize.width, size.width);
            } else {
                size.height = MAX(view.intrinsicContentSize.height, size.height);
            }
        }
    return size;
}
@end

通过这样做,顶级 UIStackView现在在分配空间时考虑嵌套 UIStackView所需的内容宽度。 [旁白:我首先尝试在嵌套的UIStackView的宽度上添加一个显式的NSLayoutConstraint,但它只是被忽略了。而返回instrinsicContentSize.width工作]

答案 2 :(得分:0)

执行此操作的一种简单方法是使用AutoLayout在嵌套堆栈视图上设置相对宽度约束。例如,如果您希望左侧UIStackView填充屏幕的2/3,而右侧UIStackView填充1/3,则可以使用以下代码。

let leftStackView = UIStackView(arrangedSubviews: [...])
leftStackView.axis = .vertical

let rightStackView = UIStackView(arrangedSubviews: [...])
rightStackView.axis = .vertical

let containerStackView = UIStackView(arrangedSubviews:
                                     [leftStackView, rightStackView])

containerStackView.axis = .horizontal
containerStackView.distribution = .fillProportionally
containerStackView.translatesAutoresizingMaskIntoConstraints = false

addSubview(containerStackView)

//leftStackView will be twice as wide as the rightStackView, so 
//the distribution is 2/3rds to 1/3rd
leftStackView.widthAnchor.constraint(equalTo:
  rightStackView.widthAnchor, multiplier: 2.0).isActive = true