【问题标题】:Autolayout: how to hide UIView containing subViews?自动布局:如何隐藏包含子视图的 UIView?
【发布时间】: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 看起来不是很吸引人。应该有比使用多个出口破坏代码更优雅的解决方案...

【问题讨论】:

    标签: objective-c uiview hide autolayout


    【解决方案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,然后在显示时设置为相等。

    因为关系是只读的,你可以这样做:

    1. 解除约束
    2. 以编程方式将其从 超级视图
    3. 设置出口等于一个新的约束, 具有相同的参数,除了您想要的
    4. 将约束重新添加到 超级视图

    基本上,您在这里所做的只是使该约束足够小,以便“大”视图的高度在隐藏时可以 == 0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-18
      • 2016-08-25
      • 2013-11-02
      • 2014-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      相关资源
      最近更新 更多