动态调整嵌套的 UIStackView
Dynamically size nested UIStackView
我有以下结构:
我的原型 TableView 单元格中有这个 StackView。在这个 StackView
里面有两个视图。第一个是正常的 'UIView' whose 内容在运行前是已知的。第二个是另一个 StackView
,我将在运行时用多个 UIViews
填充它。
内部 StackView
从一开始就设置为隐藏,只有在单击单元格时才会显示。现在我的问题是,在将这些 UIViews
动态添加到 StackView
后,我无法设法使单元格达到正确的大小(高度)。
我在更新单元格时为内部 StackView
和每个 UIView
调用 sizeToFit()
和 layoutIfNeeded()
。
这是我的代码,它填充了内部 UIStackView
(它在 java 中,因为我使用的是 multi-os-engine 但它与 swift/objective-c).
UIView parent = cell.orderDetailsView();
parent.subviews().makeObjectsPerformSelector(new SEL("removeFromSuperview"));
for (int i = 0; i < order.getOrderItems().size(); i++) {
UserOrderItem item = order.getOrderItems().get(i);
NSArray nibContents = nibBundle().loadNibNamedOwnerOptions("OrderListItem", this, null);
UIView itemView = ((UIView) nibContents.lastObject()).subviews().get(0);
parent.addSubview(itemView);
// shortened code: here I set some uilabel content inside of the itemView
if( i == 0) {
NSLayoutConstraint c1 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(itemView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Top, 1, 5);
parent.addConstraint(c1);
}
if (i == order.getOrderItems().size()-1) {
// add last item
NSArray nibContents2 = nibBundle().loadNibNamedOwnerOptions("OrderListTotalPrice", this, null);
UIView totalPriceView = ((UIView) nibContents2.lastObject()).subviews().get(0);
parent.addSubview(totalPriceView);
((UILabel) totalPriceView.subviews().get(0)).setText(DisplayUtils.getEuroString(order.getOrderFee()));
((UILabel) totalPriceView.subviews().get(1)).setText(DisplayUtils.getEuroString(order.getTotalPrice()));
NSLayoutConstraint c1 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(totalPriceView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Bottom, 1, -5);
parent.addConstraint(c1);
NSLayoutConstraint c2 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(totalPriceView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Leading, 1, 5);
parent.addConstraint(c2);
NSLayoutConstraint c3 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(totalPriceView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Trailing, 1, -5);
parent.addConstraint(c3);
}
NSLayoutConstraint c2 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(itemView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Leading, 1, 5);
parent.addConstraint(c2);
NSLayoutConstraint c3 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(itemView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Trailing, 1, -5);
parent.addConstraint(c3);
itemView.layoutIfNeeded();
itemView.setNeedsDisplay();
}
// calling sizetofit and layoutifneeded for every subview here
PS:我的外部 StackView 设置为 Fill equally
,我认为这是导致问题的原因,但是当将其设置为比例或仅填充内部 StackView
时,上面只是提示第一个元素(orderview)。
内部 StackView 设置为 fill proportionally
。
终于我发现了我的错误:我需要使用 .addArrangedSubview()
而不是 .addSubview()
。
这解决了整个问题。
我有以下结构:
我的原型 TableView 单元格中有这个 StackView。在这个 StackView
里面有两个视图。第一个是正常的 'UIView' whose 内容在运行前是已知的。第二个是另一个 StackView
,我将在运行时用多个 UIViews
填充它。
内部 StackView
从一开始就设置为隐藏,只有在单击单元格时才会显示。现在我的问题是,在将这些 UIViews
动态添加到 StackView
后,我无法设法使单元格达到正确的大小(高度)。
我在更新单元格时为内部 StackView
和每个 UIView
调用 sizeToFit()
和 layoutIfNeeded()
。
这是我的代码,它填充了内部 UIStackView
(它在 java 中,因为我使用的是 multi-os-engine 但它与 swift/objective-c).
UIView parent = cell.orderDetailsView();
parent.subviews().makeObjectsPerformSelector(new SEL("removeFromSuperview"));
for (int i = 0; i < order.getOrderItems().size(); i++) {
UserOrderItem item = order.getOrderItems().get(i);
NSArray nibContents = nibBundle().loadNibNamedOwnerOptions("OrderListItem", this, null);
UIView itemView = ((UIView) nibContents.lastObject()).subviews().get(0);
parent.addSubview(itemView);
// shortened code: here I set some uilabel content inside of the itemView
if( i == 0) {
NSLayoutConstraint c1 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(itemView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Top, 1, 5);
parent.addConstraint(c1);
}
if (i == order.getOrderItems().size()-1) {
// add last item
NSArray nibContents2 = nibBundle().loadNibNamedOwnerOptions("OrderListTotalPrice", this, null);
UIView totalPriceView = ((UIView) nibContents2.lastObject()).subviews().get(0);
parent.addSubview(totalPriceView);
((UILabel) totalPriceView.subviews().get(0)).setText(DisplayUtils.getEuroString(order.getOrderFee()));
((UILabel) totalPriceView.subviews().get(1)).setText(DisplayUtils.getEuroString(order.getTotalPrice()));
NSLayoutConstraint c1 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(totalPriceView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Bottom, 1, -5);
parent.addConstraint(c1);
NSLayoutConstraint c2 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(totalPriceView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Leading, 1, 5);
parent.addConstraint(c2);
NSLayoutConstraint c3 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(totalPriceView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Trailing, 1, -5);
parent.addConstraint(c3);
}
NSLayoutConstraint c2 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(itemView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Leading, 1, 5);
parent.addConstraint(c2);
NSLayoutConstraint c3 = NSLayoutConstraint.constraintWithItemAttributeRelatedByToItemAttributeMultiplierConstant(itemView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, parent, NSLayoutAttribute.Trailing, 1, -5);
parent.addConstraint(c3);
itemView.layoutIfNeeded();
itemView.setNeedsDisplay();
}
// calling sizetofit and layoutifneeded for every subview here
PS:我的外部 StackView 设置为 Fill equally
,我认为这是导致问题的原因,但是当将其设置为比例或仅填充内部 StackView
时,上面只是提示第一个元素(orderview)。
内部 StackView 设置为 fill proportionally
。
终于我发现了我的错误:我需要使用 .addArrangedSubview()
而不是 .addSubview()
。
这解决了整个问题。