Rya*_*huk 160 objective-c ios autolayout
我觉得这是一个相当常见的范例,显示/隐藏UIViews,通常UILabels,取决于业务逻辑.我的问题是,使用AutoLayout响应隐藏视图的最佳方式是什么,就像它们的帧是0x0一样.以下是1-3个功能的动态列表示例.

现在我从按钮到最后一个标签有一个10px的顶部空间,当标签被隐藏时,显然不会向上滑动.到目前为止,我创建了这个约束的出口,并根据我显示的标签数量修改常量.这显然有点hacky,因为我使用负常量值将按钮向上推到隐藏的帧上.这也很糟糕,因为它不受实际布局元素的限制,只是基于其他元素的已知高度/填充的偷偷摸摸的静态计算,并且明显地与AutoLayout的构建作斗争.
我显然可以根据我的动态标签创建新的约束,但这是很多微观管理和尝试折叠一些空白的很多冗长.有更好的方法吗?更改帧大小0,0并让AutoLayout在没有约束操作的情况下完成它的工作?完全删除视图?
但老实说,只需从隐藏视图的上下文修改常量,只需要一行代码就可以进行简单的计算.重新创建新的约束 constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:似乎很重.
编辑2018年2月:用UIStackViews 来看Ben的回答
Max*_*eod 232
我个人对显示/隐藏视图的偏好是创建一个具有适当宽度或高度约束的IBOutlet.
然后我将constant值更新0为隐藏,或者应显示的值.
该技术的最大优点是将保持相对约束.例如,假设您有视图A和视图B,水平间隙为x.当视图A宽度constant设置0.f为时,视图B将向左移动以填充该空间.
无需添加或删除约束,这是一项重量级操作.简单地更新约束constant就可以了.
Sim*_*lGy 96
0隐藏时使用常量和再次显示常量时使用常量的解决方案是有效的,但如果您的内容具有灵活的大小,则不满意.您需要测量灵活内容并设置一个不变的状态.这感觉不对,如果内容因服务器或UI事件而改变大小,则会出现问题.
我有一个更好的解决方案.
我们的想法是在隐藏元素时将0高度规则设置为具有高优先级,以便它不占用自动布局空间.
这是你如何做到这一点:
1.在接口构建器中以低优先级设置宽度(或高度)为0.

Interface Builder不会对冲突大喊大叫,因为优先级很低.通过暂时将优先级设置为999来测试高度行为(禁止1000以编程方式进行变异,因此我们不会使用它).接口构建器现在可能会对冲突的约束大喊大叫.您可以通过将相关对象的优先级设置为900左右来解决这些问题.
2.添加插座,以便您可以在代码中修改宽度约束的优先级:

3.隐藏元素时调整优先级:
cell.alertTimingView.hidden = place.closingSoon != true
cell.alertTimingWidth.priority = place.closingSoon == true ? 250 : 999
Run Code Online (Sandbox Code Playgroud)
Ben*_*ard 81
UIStackView可能是iOS 9+的方法.它不仅处理隐藏的视图,如果设置正确,它还将删除额外的间距和边距.
Mit*_*iya 11
在这种情况下,我将Author标签的高度映射到适当的IBOutlet:
@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;
Run Code Online (Sandbox Code Playgroud)
当我将约束的高度设置为0.0f时,我们保留"填充",因为"播放"按钮的高度允许它.
cell.authorLabelHeight.constant = 0; //Hide
cell.authorLabelHeight.constant = 44; //Show
Run Code Online (Sandbox Code Playgroud)
这里有很多解决方案,但是我通常的方法又有所不同:)
设置两组约束,类似于Jorge Arimany和TMin的答案:
这三个标记的约束的常数值都相同。标记为A1和A2的约束将其优先级设置为500,而标记为B的约束将其优先级设置为250(或UILayoutProperty.defaultLow在代码中)。
将约束B连接到IBOutlet。然后,当您隐藏元素时,只需将约束优先级设置为高(750):
constraintB.priority = .defaultHigh
但是,当该元素可见时,将优先级设置回低(250):
constraintB.priority = .defaultLow
与仅更改isActive约束B 相比,此方法的优点(公认的次要优势)是,如果通过其他方法从视图中删除了过渡元素,您仍然会有工作约束。
对视图进行子类化并覆盖func intrinsicContentSize() -> CGSize.CGSizeZero如果视图被隐藏,则返回.
我刚刚发现要让 UILabel 不占用空间,您必须隐藏它并将其文本设置为空字符串。(iOS 9)
知道这个事实/错误可以帮助一些人简化他们的布局,甚至可能是原始问题的布局,所以我想我会发布它。
| 归档时间: |
|
| 查看次数: |
89116 次 |
| 最近记录: |