自动布局:如何隐藏包含子视图的 UIView?
Posted
技术标签:
【中文标题】自动布局:如何隐藏包含子视图的 UIView?【英文标题】:Autolayout: how to hide UIView containing subViews? 【发布时间】:2014-07-11 12:29:56 【问题描述】:使用新的 Autolayout 隐藏视图的最佳解决方案肯定是为视图创建高度约束,连接它并为其创建一个出口,并将 self.myViewHeightConstriant.constant 更改为 0。但假设视图包含其他一些视图,假设一个 imageView 和它下面的一些标签。现在,imageView 距离顶部 10px 并且具有顶部空间到具有 10px 值的 superview 约束。尝试使用常量 = 0 隐藏容器 UIView 在控制台中显示错误:
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this: (1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't
understand, refer to the documentation for the UIView property
translatesAutoresizingMaskIntoConstraints)
(
<NSLayoutConstraint:0xc7cedb0 V:[UIView:0xc7ce1e0(0)]>,
<NSLayoutConstraint:0xc7ceea0 V:[UIImageView:0xc7ce270]-(0)-| (Names: '|':UIView:0xc7ce1e0 )>,
<NSLayoutConstraint:0xc7cef30 V:|-(10)-[UIImageView:0xc7ce270] (Names: '|':UIView:0xc7ce1e0 )>
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0xc7ceea0 V:[UIImageView:0xc7ce270]-(0)-| (Names: '|':UIView:0xc7ce1e0 )>
猜测问题是容器 UIView 的高度为 0,但 imageView 的顶部空间偏移量为 10px,并且 Autolayout 引擎不了解如何处理这种情况。试图为容器视图设置 clipSubviews 但这没有帮助。有什么想法吗?
更新 几个想法,为 imageView 创建一个出口 topSpaceToSuperView 约束并将其约束也设置为 0 看起来不是很吸引人。应该有比使用多个出口破坏代码更优雅的解决方案...
【问题讨论】:
【参考方案1】:container.hidden = YES
不能简单吗?
否则,破坏事物的是底部约束。 @"V:|-10-[imageView]|"
告诉容器视图必须至少 10 pts 高。但是@"V:|-10-[imageView]"
会很好。
也许不是将 imageView 锚定到容器的底部,而是为 imageView 的高度设置一个约束。
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[imageView]"
options:nil
metrics:nil
views:views];
[NSLayoutConstraint constraintWithItem:self.imageView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.containerView
attribute:NSLayoutAttributeHeight
multiplier:1.
constant:-10.f];
更新
您在 cmets 中提到 imageView 不是可预测的高度。既然如此,只管理容器的高度可能更容易,但要使用单独的约束:
containerOpen = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[imageView]|"
options:nil
metrics:nil
views:views];
containerClosed = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[containerView(0)]"
options:nil
metrics:nil
views:views];
// Toggle between the constraints to open close the container
- (void)toggleContainer
[self.containerView.superview removeConstraints:containerOpen];
[self.containerView.superview removeConstraints:containerClosed];
self.containerView.isOpen = !self.containerView.isOpen;
if (self.containerView.isOpen)
[self.containerView.superview addConstraints:containerOpen];
else
[self.containerView.superview addConstraints:containerClosed];
[self.containerView.superview setNeedsUpdateConstraints];
[self.containerView setNeedsLayout];
[self.containerView layoutIfNeeded];
【讨论】:
不,我不能只隐藏,因为容器视图位于另一个容器视图中,并且还有其他视图。隐藏我的容器视图应该将其他容器视图移到顶部,但简单的隐藏不会这样做。另外,imageView是从后端接收的,所以它的高度是动态的,所以我需要把它的顶部和底部贴在superView上,并通过设置containerView的高度来扩展到需要的大小。但是,谢谢,关于底部空间 + imageView 高度的好消息。因此,将拥有并管理 containerViewHeight 和 imageViewHeigh。可能没有其他方法存在。 关于约束的快速说明,我尝试在界面生成器中创建约束,而不是在代码中。将业务逻辑(代码)与可视化部分分开更有意义。但我想这是一个问题...... @Centurion 我在这里又举了一个例子,因为你说你的图像有不同的高度(即容器视图的高度决定了图像的高度)。让我知道这是否有用,否则我会删除它。 另外,我是那些“拒绝使用界面生成器”的人之一。我认为它为自动布局增加了很多 GUI 复杂性,这在一天结束时是一件相当简单的事情。但这只是我。【参考方案2】:如果您有一个前导、尾随、顶部或底部约束,您可以在隐藏时将关系设置为 LessThanOrEqual,然后在显示时设置为相等。
因为关系是只读的,你可以这样做:
-
解除约束
以编程方式将其从
超级视图
设置出口等于一个新的约束,
具有相同的参数,除了您想要的
将约束重新添加到
超级视图
基本上,您在这里所做的只是使该约束足够小,以便“大”视图的高度在隐藏时可以 == 0。
【讨论】:
以上是关于自动布局:如何隐藏包含子视图的 UIView?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用自动布局在 UIScrollView 中为视图高度设置动画?
UIScrollView 作为 UIView 的子视图不适用于自动布局