【问题标题】:Resizing UIView with autolayout when placed below a fixed size UIView当放置在固定大小的 UIView 下方时,使用自动布局调整 UIView 的大小
【发布时间】:2013-07-30 07:14:50
【问题描述】:

我在这个布局中使用自动布局:

self.view with frame (0,80, 320, 488)

带有框架的collectionView (0,0,320,220)

underView with frame (0,220,320,268)

并尝试实现一个动画,该动画应该调整 underView 的大小以扩大其高度,以便 underView 部分覆盖 collectionView 自下而上的移动。

Autolayout 为这两个视图强制设置高度约束,因此我为 underView 高度约束创建了一个 IBOutlet,我在动画中对其进行了调整:

NSLog(@"underView height %.2f", self.underView.frame.size.height);

NSLog(@"offset (%.2f, %.2f)", offset.x, offset.y);

heightConstraint.constant += offset.y;

NSLog(@"heightConstraint %.2f", heightConstraint.constant);

[self.underView setNeedsUpdateConstraints];

[UIView animateWithDuration:ANIMATION_DURATION
                      delay:ANIMATION_DELAY
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{

                     [self.underView layoutIfNeeded];

                     NSLog(@"underView height %.2f", heightConstraint.constant);

                 } completion:nil];

在控制台中我可以看到:

2013-07-30 09:09:37.268 Cal[49611:a0b] underView height 268.00
2013-07-30 09:09:37.268 Cal[49611:a0b] offset (320.00, 144.00)
2013-07-30 09:09:37.269 Cal[49611:a0b] heightConstraint 412.00
2013-07-30 09:09:37.270 Cal[49611:a0b] underView height 412.00

但是根本没有调整大小。

我能想到的这种行为的唯一原因是上面collectionView的高度限制,但是由于我不希望重新加载集合,所以我无法对其进行操作。

我想知道如何实现让 underView 放大到 collectionView 之上?我尝试使用约束优先级,但没有奏效...

【问题讨论】:

    标签: ios autolayout nslayoutconstraint


    【解决方案1】:

    按照this answer 尝试以下操作。确保在 superview 上调用 layoutIfNeeded:

    [UIView animateWithDuration:ANIMATION_DURATION
                          delay:ANIMATION_DELAY
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
    
                         heightConstraint.constant += offset.y;
                         [self.view layoutIfNeeded];
    
                         } 
                     completion:nil];
    

    【讨论】:

    • 谢谢@Maarten,但实际上这没有任何区别,此外,如果您阅读 cmets 到您链接的答案,人们已经确认不断更新可以很好地远离动画,只在动画块中留下 layoutIfNeeded 方法。作为一个额外的提示,我也尝试调用 [self.view layoutIfNeeded] 有人指出是需要重新显示布局的超级视图,但没有任何改变。
    • 你试过在superView上调用layoutIfNeeded吗?我更改了答案以反映这一点。
    • 是的,正如我上面所说,self.view 是超级视图。
    • 但是在您的代码中,您在underView 上调用layoutIfNeeded,而不是self.view,就像我在回答中所做的那样。
    • @Marteen,在我上面的第一条评论中:“作为附加提示,我还尝试调用 [self.view layoutIfNeeded] 有人指出是需要重新显示布局的超级视图,但没有任何改变再次”。
    【解决方案2】:

    所以,我找到了一个可能的解决方案来解决我的问题,但不确定它是否是最好的解决方案。我缺少对 self.collectionView 的垂直空间约束的引用,所以最终代码是:

    verticalSpace.constant -= shift;
    heightConstraint.constant += shift;
    
    [self.collectionView setNeedsUpdateConstraints];
    [self.underView setNeedsUpdateConstraints];
    
    [UIView animateWithDuration:ANIMATION_DURATION
                          delay:ANIMATION_DELAY
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         [self.view layoutIfNeeded];
                     } completion:nil
     ];
    

    我会等待其他更好的解决方案一段时间,这样我就不会将自己的答案标记为已接受的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 2015-04-14
      • 1970-01-01
      相关资源
      最近更新 更多