2016-01-08 54 views
2

我正在尝试动画UILabel的宽度。出于某种原因,动画不起作用,标签立即改变大小。我使用自动布局。这里是我写的重现这个示例项目的代码。点击按钮可更改按钮和标签的尾随限制。使用自动布局动画UILabel宽度

@interface ViewController() 

@property (assign, nonatomic) BOOL controlsResized; 
@property (weak, nonatomic) IBOutlet UIButton *button; 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *buttonTrailingConstraint; 
@property (weak, nonatomic) IBOutlet MyLabel *label; 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelTrailingConstraint; 
- (IBAction)doTapButton:(id)sender; 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    [self.button setTranslatesAutoresizingMaskIntoConstraints:NO]; 
    [self.label setTranslatesAutoresizingMaskIntoConstraints:NO]; 
    self.label3.text = @"asdfasdfds sklfjfjls sdlkfj jjjjkfjkfdsjkdfsjklffsjkfdsjkl"; 
}  


- (IBAction)doTapButton:(id)sender 
{ 
    if (!self.controlsResized) 
    { 
     [UIView animateWithDuration:0.5 animations:^{ 
      self.buttonTrailingConstraint.constant = 0; 
      [self.button layoutIfNeeded]; 
      self.labelTrailingConstraint.constant = 0; 
      [self.label layoutIfNeeded]; 

      self.controlsResized = YES; 
     }]; 
    } 
    else 
    { 
     [UIView animateWithDuration:0.5 animations:^{ 
      self.buttonTrailingConstraint.constant = 100; 
      [self.button layoutIfNeeded]; 
      self.labelTrailingConstraint.constant = 100; 
      [self.label layoutIfNeeded]; 

      self.controlsResized = NO; 
     }]; 
    } 
} 

@implementation MyLabel 

- (void)drawTextInRect:(CGRect)rect 
{ 
    NSLog(@"drawTextInRect"); 
    [super drawTextInRect:rect]; 
} 

@end 

正如你可以在video看到,它的工作原理为按钮,但对于标签不起作用。

我试图从MyLabel类调​​查和subclassed标签。看起来,- (void)drawTextInRect:(CGRect)rect立即被按钮按钮调用,作为[self.label layoutIfNeeded];在动画块中的原因。为什么这样?我会期望帧被改变为动画,因为它被设置在动画块内。它和UIButton的预期一样。

为什么UILabel不调整动画大小?有没有办法解决它?

编辑: 我尝试了当前答案中提出的方法,但它们也不起作用。我认为动画代码在这里不是问题,因为它适用于我的示例中的按钮。这个问题似乎与UILabel具体有关。 UILabel似乎处理动画的大小变化不同于其他UIView子类,但我不明白为什么。

+0

你的代码显示篡改的证据:它集'自我。 label3.text'但是'ViewController'没有'label3'属性。当你没有向我们展示你真实的代码时,很难帮助你。无论如何,我怀疑你的标签在故事板中的设置方式存在问题。 –

回答

2

我会发表评论,但我没有必要的声誉。这里是我会做什么:

self.buttonTrailingConstraint.constant = x; 
self.labelTrailingConstraint.constant = x; 

[UIView animateWithDuration:0.5 animations:^{ 

    [self.view layoutIfNeeded]; 
}]; 

当你更新你需要考虑到要修改相应的视图的约束并不需要更新的唯一一个约束,所以布局方法调用是更好的做在父视图上。

这对我来说每次都有效。希望这可以帮助。

+3

这也是我最初的反应,但我在我自己的测试中遇到了一个奇怪的行为:它在扩展标签时非常完美,但是当它再次减少时,它会跳跃......奇怪。 – jcaron

+0

@Bogdan Balta:我明白你的意思,你提出了制定动画约束的标准方法,并且我知道它。然而,这不是我的代码中的问题,因为按钮动画与预期的一样。问题是UILabel特定的。我会改变我的代码,因为它显然混淆了人。请让我知道,如果你可以让你的动画代码与UILabel一起工作。 – Anastasia

+0

@Bogdan Balta:你似乎是对的,这确实是调用[self.view layoutIfNeeded]的问题; – Anastasia

2

在动画之前,您必须设置约束的常量。

试试这个:

- (IBAction)doTapButton:(id)sender 
{ 
    if (!self.controlsResized) 
    { 
     self.buttonTrailingConstraint.constant = 0; 
     self.labelTrailingConstraint.constant = 0; 

     [UIView animateWithDuration:0.5 animations:^{ 
      [self.view layoutIfNeeded]; 
     } completion:^(BOOL finished) { 
      self.controlsResized = YES; 
     }]; 
    } 
    else 
    { 
     self.buttonTrailingConstraint.constant = 100; 
     self.labelTrailingConstraint.constant = 100; 

     [UIView animateWithDuration:0.5 animations:^{ 
      [self.view layoutIfNeeded]; 
     } completion:^(BOOL finished) { 
      self.controlsResized = NO; 
     }]; 
    } 
} 
+0

不,我明白你的意思,你提出了制定动画约束的标准方法,我知道它。然而,这不是我的代码中的问题,因为按钮动画与预期的一样。问题是UILabel特定的。我会改变我的代码,因为它显然混淆了人。请让我知道,如果你可以让你的动画代码与UILabel一起工作。 – Anastasia

+0

它适用于我与一个UILabel .. – Pipiks

+0

嗯,你的代码确实有效,谢谢。 – Anastasia

2

有几个部分来使这个100%按预期方式工作:

  • 呼叫layoutIfNeeded第一
  • 设置动画块
  • 的约束不变外
  • 调用layoutIfNeeded块内

从工作实现复制:

[self.view layoutIfNeeded]; 
self.topContainerConstraint.constant = constraintValue; 
[UIView animateWithDuration:0.25 animations:^{ 
    [self.view layoutIfNeeded]; 
} completion:^(BOOL finished){ }]; 

我想你的功能更改为类似以下的(显然未经测试):

- (IBAction)doTapButton:(id)sender 
{ 
    if (!self.controlsResized) 
    { 
     [self.view layoutIfNeeded]; 
     self.labelTrailingConstraint.constant = 0; 
     self.buttonTrailingConstraint.constant = 0; 
     [UIView animateWithDuration:0.5 animations:^{ 
      [self.view layoutIfNeeded]; 
      self.controlsResized = YES; 
     }]; 
    } 
    else 
    { 
     [self.view layoutIfNeeded]; 
     self.labelTrailingConstraint.constant = 100; 
     self.buttonTrailingConstraint.constant = 100; 
     [UIView animateWithDuration:0.5 animations:^{ 
      [self.view layoutIfNeeded]; 
      self.controlsResized = NO; 
     }]; 
    } 
} 
+0

不,我明白你的意思,你提出了制定动画约束的标准方法,并且我知道它。然而,这不是我的代码中的问题,因为按钮动画与预期的一样。问题是UILabel特定的。我会改变我的代码,因为它显然混淆了人。请让我知道,如果你可以让你的动画代码与UILabel一起工作。 – Anastasia

+0

是的,它的工作原理,谢谢。 – Anastasia

+0

太棒了!我只是连线演示来验证。 :) – Ben