如何使用内部 XIB 为动态 UIStackView 设置对齐方式
Posted
技术标签:
【中文标题】如何使用内部 XIB 为动态 UIStackView 设置对齐方式【英文标题】:How to set alignments right for dynamic UIStackView with inner XIB 【发布时间】:2018-11-02 13:48:13 【问题描述】:我原来的ViewController
只包含一个这样的滚动视图:
现在我也有了自己的xib
文件(CheckBoxView),主要由一个按钮组成,看这个截图:
我动态创建一些UIStackView
s 并将它们添加到ScrollView
在这些UIStackView
s 中我添加了我的xib
文件的多个实例。
我想要实现的是,StackViews 只是垂直堆叠。在 StackViews 中,我的 xib 文件中的 UIView
s 也应该垂直堆叠。
目前它看起来像这样:
所以 xib 视图不在整个视图中。由于我使用的是多操作系统引擎,我无法提供 swift/obj-c 代码。但这是我的 Java 代码:
for (ItemConfiguration config : itemInstance.getConfigurations())
List<DLRadioButton> radioButtons = new ArrayList<DLRadioButton>();
UIStackView configView = UIStackView.alloc().initWithFrame(new CGRect(new CGPoint(0, barHeight), new CGSize(displayWidth, displayHeight - barHeight)));
configView.setAxis(UILayoutConstraintAxis.Vertical);
configView.setDistribution(UIStackViewDistribution.EqualSpacing);
configView.setAlignment(UIStackViewAlignment.Center);
configView.setSpacing(30);
for (ConfigurationOption option : config.getOptions())
UIView checkBox = instantiateFromNib("CheckBoxView");
for (UIView v : checkBox.subviews())
if (v instanceof DLRadioButton)
((DLRadioButton) v).setTitleForState(option.getName(), UIControlState.Normal);
//((DLRadioButton) v).setIconSquare(true);
radioButtons.add((DLRadioButton) v);
configView.addArrangedSubview(checkBox);
// group radiobuttons
//groupRadioButtons(radioButtons);
configView.setTranslatesAutoresizingMaskIntoConstraints(false);
scrollView().addSubview(configView);
configView.centerXAnchor().constraintEqualToAnchor(scrollView().centerXAnchor()).setActive(true);
configView.centerYAnchor().constraintEqualToAnchor(scrollView().centerYAnchor()).setActive(true);
private UIView instantiateFromNib(String name)
return (UIView) UINib.nibWithNibNameBundle(name, null).instantiateWithOwnerOptions(null, null).firstObject();
我需要如何设置对齐方式等以实现我想要的。它应该是这样的:
【问题讨论】:
你的代码中barHeight
的值是多少?
@AleksandrMedvedev 这是UIApplication.sharedApplication().statusBarFrame().size().height();
大约 35 块类似的矿石。它只是顶部的状态栏高度。但是既然你提到它,这个UIStackView
的大小不应该是静态的。它应该随着内容动态增长,因此如果内容过多,它会因为外部UIScrollView
而变得可滚动
如果您包含一个演示项目,它将更快地解决
【参考方案1】:
我不知道是否有理由不使用UITableView,我强烈建议您使用它。如果不可能,您可以在下面找到一些应该有所帮助的建议。
如果您使用自动布局,您应该为代码中实例化的所有视图设置约束。约束必须全面,ios 才能知道每个视图的位置和大小。
去除多余的约束
configView.centerXAnchor().constraintEqualToAnchor(scrollView().centerXAnchor()).setActive(true);
configView.centerYAnchor().constraintEqualToAnchor(scrollView().centerYAnchor()).setActive(true);
这两个约束对我来说没有意义。您需要将 stackviews 堆叠在 ScrollView 中,但不要居中。如果我正确理解您的目标,则应将其删除
为 UIStackViews 设置宽度/x 位置约束
configView.setTranslatesAutoresizingMaskIntoConstraints(false);
scrollView().addSubview(configView);
在将堆栈视图添加到 ScrollView 之后,您需要为其设置约束。我会迅速提供我的代码,但它看起来与您的 Java 代码所做的非常相似,所以希望您能够毫无困难地转换它:
NSLayoutConstraint.activate([
configView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor),
configView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor)
]);
为 UIStackViews 设置高度限制
每当您在其中添加排列视图时,StackViews 都不会改变它们的大小。因此,您需要自己计算所需的 stackview 大小并通过约束明确指定它。它应该足以容纳物品和它们之间的空间。我想所有的项目应该是相同的大小,让它是 32 点,那么高度应该是:
let stackViewHeight = items.count * 32 + stackView.space * (items.count + 1)
并为堆栈视图创建新的高度约束:
configView.heightAnchor.constraint(equalToConstant: stackViewHeight).isActive = true
为 UIStackView 设置 y 位置
这是一个更具挑战性的部分,但最重要的是视图在滚动视图中正常工作。
1) 更改循环以了解 UIStackView 的索引
滚动视图应该始终知道其内容的高度,因此您需要了解哪个堆栈视图是顶部,哪个是底部。为此,您需要将每个循环更改为 for(;;) 循环:
for (int i = 0; i < itemInstance.getConfigurations().length; i++)
ItemConfiguration config = itemInstance.getConfigurations()[i]
...
我不知道你的数组是哪种类型,所以如果它没有下标功能,只需将其替换为相应的方法即可。
2) 设置堆栈视图的顶部锚点
对于数组中的第一个堆栈视图,顶部锚点应该等于滚动视图顶部锚点,对于其他应该是前一个堆栈视图的底部锚点 + 它们之间的间距(例如,本示例中的 8 个点):
if i == 0
configView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor, constant: 8).isActive = true
else
let previousConfigView = itemInstance.getConfigurations()[i - 1]
configView.topAnchor.constraintEqualToAnchor(previousConfigView.bottomAnchor, constant: 8).isActive = true
3) 为最后一个堆栈视图设置底部锚点
如前所述 - 为了让 Scroll View 了解内容大小,我们需要指定相应的约束:
if i == itemInstance.getConfigurations() - 1
configView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor, constant: 8).isActive = true
注意:请注意,所有约束都应设置在已添加到滚动视图的视图上。
【讨论】:
我需要在UITableView
中使用UITableView
,不是吗?这不是问题吗?我可以在每个单元格中添加一个UITableView
并在内层添加我的 XIB 视图吗?感谢你的付出!我现在会调查你的答案:) 只是好奇使用 UITableView 是否会更好
@progNewbie,你不需要使用嵌套的UITableView
s。相反,您可以在单个 UITableView
中创建几个部分,在数据源委托中实现相应的方法 - developer.apple.com/documentation/uikit/uitableviewdatasource/…
谢谢,我试试这个。以上是关于如何使用内部 XIB 为动态 UIStackView 设置对齐方式的主要内容,如果未能解决你的问题,请参考以下文章