iOS动画标签展开

iOS动画标签展开,ios,uilabel,core-animation,Ios,Uilabel,Core Animation,我有一个UILabel,它由3行文本启动: locationDescription = [[UILabel alloc]init]; locationDescription.numberOfLines = 3; [locationDescription setTranslatesAutoresizingMaskIntoConstraints:NO]; [self addSubview:locationDescription]; 然后,我有一个按钮展开标签: - (void)buttonPres

我有一个UILabel,它由3行文本启动:

locationDescription = [[UILabel alloc]init];
locationDescription.numberOfLines = 3;
[locationDescription setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:locationDescription];
然后,我有一个按钮展开标签:

- (void)buttonPressed:(UIButton *)sender{
    NSLog(@"Pressed");
    [UIView animateWithDuration:1
                     animations:^{locationDescription.numberOfLines = 0;}
     ];
}
标签所需的行为是让每条额外的线一次显示一条。标签可以很好地展开,但过渡并没有设置动画,所有的线条都会立即显示出来


我遗漏了什么?

您不能设置行数动画,您应该设置大小动画,并从一开始就将行数设置为0

我没有添加高度计算代码,因为它会在这里隐藏真实动画

self.locationDescription = [[UILabel alloc] init];
self.locationDescription.numberOfLines = 0;
[locationDescription setTranslatesAutoresizingMaskIntoConstraints:NO];

// Say, it starts with 50. In your real code, height should be calculated
// to fit the size you want, rounded to lines
NSDictionary *viewsDict = @{@"locationDescription": self.locationDescription};
[self.locationDescription addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"V:[locationDescription(50)]"
                                         options:0 metrics:nil
                                           views:viewsDict];
那么在行动中,做什么

- (void)buttonPressed:(UIButton *)sender
{
    NSLog(@"Pressed");
    // Assuming there is only one constraint. If not, assign it to another property
    // I put 500, but, again, real size rounded to line height should be here
    self.locationDescription.constraints[0].constant = 500;
    [UIView animateWithDuration:1 animations:^{
        // Layouting superview, as its frame can be updated because of a new size
        [self.locationDescription.superview layoutIfNeeded];
    }];
}

此外,您应该将
locationDescription
指定给属性,并使用前面的
self.
访问该属性。

UIView animateWithDuration的块对象包含提交到视图的更改。这是以编程方式更改视图层次中视图的任何可设置动画的属性的地方。但是您指定的属性numberOfLines不是可设置动画的属性

UILabel的父类UIView类的以下属性可设置动画:

 @property frame
 @property bounds
 @property center
 @property transform
 @property alpha
 @property backgroundColor
 @property contentStretch

可以设置线数的动画。它更改
UILabel
的内部大小。您需要在包含UILabel的视图上的动画块内调用LayoutIfNeed。在这里,我在表格上附加了一个点击手势,以便在0行和1行之间切换

 func tapLabel(tapGesture: UITapGestureRecognizer)
 {
    if let label = tapGesture.view as? UILabel {
      label.numberOfLines = label.numberOfLines == 0 ? 1 : 0
      UIView.animateWithDuration(0.5) {
        label.superview?.layoutIfNeeded()
      }
    }
 }

设置动画主体外部的线数,然后设置动画主体内部的线数。这是打字错误吗?是的,对不起。代码已编辑。可能不是问题,但仍然:-init不是UILabel的指定初始值设定项--请使用-initWithFrame:。@Caleb-initforUIView相当于initWithFrame:CGRectZero,因此调用-init完全可以。只有当覆盖这一点变得重要时,@coverback很高兴知道——我想这是我第二次了解这一点谢谢。我实际上是从这开始做的,但所需的布局似乎也会重新绘制文本,因此当对象设置动画时,文本和边界框都会四处移动。@sheepgobeep一个选项是使用
tttatAttributedLabel
,它支持垂直对齐,在这种情况下,文本将保持在同一位置,展示新台词。这很有效。一个问题:根据我的经验,label.numberOfLines必须从0开始。通过“查看”下的“内容模式”到“顶部”,它将顺利显示隐藏的行…@AxelZehden这是我一直在寻找的答案@AxelZehden:尊重。嗨,谢谢你的回答,有没有可能让动画的标签只是向下“扩展”呢?答案中的一个看起来像是文本会从标签边界的顶部滚动进来。