【问题标题】:Autolayout animate constraint does not animate subviews自动布局动画约束不动画子视图
【发布时间】:2013-12-04 13:01:06
【问题描述】:

我有一个 UIView,其中有一个 UILabel 作为子视图。

现在我用动画改变 UIView 的宽度(改变约束的常量属性)并在 UIView 动画中调用 layoutIfNeeded...)

视图正在正常调整大小, UILabel(子视图)将字体大小更改为“结束”大小,但没有像 uiview 那样正确设置动画。

根据 WWDC 2012 会议,如果仅更改超级视图的常量,则子视图应设置动画。

UILabel 的最小字体比例为 0,1,小于必须调整大小的字体。

【问题讨论】:

    标签: ios objective-c animation constraints autolayout


    【解决方案1】:

    我正在努力通过更改 width 约束来调整 UILabel 大小的动画。标签设置了adjustsFontSizeToFitWidthminimumScaleFactor

    我通过将标签的 contentMode 设置为 UIViewContentModeScaleAspectFit 来修复它。默认情况下,标签是UIViewContentModeLeft

    【讨论】:

      【解决方案2】:

      我认为您不能以这种方式为文本的大小设置动画。我能想到的唯一方法是创建标签的快照视图,在标签上添加该视图,执行动画,然后删除快照视图。这段代码确实将较小的文本略微向下移动,但它看起来相当不错,当您取消隐藏标签并移除图像视图时只有非常小的移动。包含标签的小视图大小为 185x36,标签的约束为 smallView 的每一侧为 20,顶部为 8,底部为 7。我在代码中将这些相同的约束添加到图像视图中。

      @interface ViewController ()
      @property (weak, nonatomic) IBOutlet NSLayoutConstraint *widthCon; // width constraint on smallView
      @property (weak,nonatomic) IBOutlet UIView *smallView; // view that the label is embedded in
      @property (weak,nonatomic) IBOutlet UILabel *label;
      @end
      
      @implementation ViewController
      
      - (IBAction)shrinkView:(id)sender {
      
          UIView *snapshot = [self.label snapshotViewAfterScreenUpdates:YES];
          [snapshot setTranslatesAutoresizingMaskIntoConstraints:NO];
          [self.smallView addSubview:snapshot];
          [self.smallView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[snapshot]-20-|" options:0 metrics:nil views:@{@"snapshot":snapshot}]];
          NSLayoutConstraint *topCon = [NSLayoutConstraint constraintWithItem:snapshot attribute:NSLayoutAttributeTop relatedBy:0 toItem:self.smallView attribute:NSLayoutAttributeTop multiplier:1 constant:8];
          NSLayoutConstraint *bottomCon = [NSLayoutConstraint constraintWithItem:self.smallView attribute:NSLayoutAttributeBottom relatedBy:0 toItem:snapshot attribute:NSLayoutAttributeBottom multiplier:1 constant:7];
          [self.smallView addConstraints:@[topCon,bottomCon]];
          [self.smallView layoutSubviews];
          self.label.alpha = 0;
          self.widthCon.constant = 100;
          topCon.constant = 18;
          bottomCon.constant = 10;
          [UIView animateWithDuration:.5 animations:^{
                  [self.view layoutIfNeeded];
              } completion:^(BOOL finished) {
                  self.label.alpha = 1;
                  [snapshot removeFromSuperview];
              }];
      }
      

      编辑后:

      有一种方法可以为视图设置动画,这样标签也可以向下设置动画,而不是立即变为最终大小。您必须使用计时器直接为约束设置动画(查看 WWDC 2012 视频中大约 31 分钟的解释,“掌握自动布局的最佳实践”)。这可以为标签的大小设置动画,但是字体大小的变化很跳跃,看起来不太好。如果您对标签所在的视图有宽度限制(并且标签对两侧有限制),那么您可以这样做:

      -(IBAction)animateSizeChange:(id)sender {
          [NSTimer scheduledTimerWithTimeInterval:.001 target:self selector:@selector(doStuff:) userInfo:Nil repeats:YES];
      }
      
      -(void)doStuff:(NSTimer *) aTimer {
          self.widthCon.constant -= .2;
          if (self.widthCon.constant <90) [aTimer invalidate];
      }
      

      【讨论】:

      • 不幸的是,使用计时器进行后编辑的代码看起来也很跳跃……:/
      • 快照的想法很老套,不应该这样接近,你不觉得吗?
      • @Christian'fuzi'Orgler,不,我认为这根本不是 hacky。苹果在他们自己的一些动画中使用了这个“技巧”。另外,还有什么办法?至于你的第一条评论,是的,它很跳跃,这就是我所说的——我包括在内只是为了展示一种你可以为视图的子视图设置动画的方式,如果你不想缩小文本大小,有时效果很好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-05
      • 1970-01-01
      • 1970-01-01
      • 2014-05-26
      • 1970-01-01
      • 2015-07-31
      • 2015-04-02
      相关资源
      最近更新 更多