动画约束更改,定位动画但高度跳跃没有动画 [英] Animating Constraint Changes, position animates but height jumps without animation
问题描述
我有一个自定义的UIView。在UIView中,我有一个带有黄色背景的UILabel,其中包含@8,名为 labelWhite
。我以编程方式为该UILabel创建了4个约束:top,left,width和height。
I have a custom UIView. Within that UIView I have a UILabel with a yellow background containing @"8" called labelWhite
. I programmatically create 4 constraints for that UILabel: top, left, width, and height.
当我点击UIView时,我会更改高度的常量值并在5秒内为布局设置动画。但是,视图的高度会立即跳转到新值,但y位置也会立即更改并跳转到新值。然后在5秒的动画中,y位置动画回到它应该一直保持的位置。
When I tap the UIView, I change the constant value of the height and animate the layout over 5 seconds. However, the height of the view immediately jumps to the new value, but the y position also changes and jumps to a new value immediately. Then over the 5 second animation, the y position animates back to where it should have stayed all along.
你可以在这里看到它的视频: http://inadaydevelopment.com/stackoverflow/Constraints0.mov
You can see a video of it happening here: http://inadaydevelopment.com/stackoverflow/Constraints0.mov
它应该做的只是保持在y = 0并垂直缩小。我做错了什么?
What it SHOULD do is just remain at y=0 and shrink vertically. What am I doing wrong?
编辑:
I刚发现如果我的子视图是UIViews,我的动画完全按预期工作,但作为UILabels,我得到了跳跃大小+动画位置。
I just discovered that my animations work exactly as intended if my subviews are UIViews, but as UILabels I get the jump-size + animate-position.
发生了什么?有没有办法让UILabels为它们的大小设置动画?
What is going on? Is there a way I can get UILabels to animate their size?
这是我用来修改和动画的代码布局:
This is the code I use to modify and animate the layout:
self.constraintWhiteHeight.constant = secondaryHeight;
[UIView animateWithDuration:5.0 animations:^{
[self layoutIfNeeded];
}];
这是我用来创建约束的代码:
This is the code I use to create the constraints:
// ------ Top -----
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.labelWhite
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0];
[self addConstraint:constraint];
// ------ Left -----
self.constraintWhiteLeft = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.labelWhite
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0];
// ------ Width -----
NSString *constraintString = [NSString stringWithFormat:@"H:[_labelWhite(==%.0f)]", self.bounds.size.width];
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraintString
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_labelWhite)];
NSLog(@"constraints: %@", constraints);
self.constraintWhiteWidth = [constraints objectAtIndex:0];
[self.labelWhite addConstraints:constraints];
// ------ Height -----
constraintString = [NSString stringWithFormat:@"V:[_labelWhite(==%.0f)]", primaryHeight];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraintString
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_labelWhite)];
self.constraintWhiteHeight = [constraints objectAtIndex:0];
[self.labelWhite addConstraints:constraints];
推荐答案
我不认为你做错了什么,这似乎是当您尝试设置其高度动画时标签的行为方式。我知道我过去曾经解决过这个问题,我不记得我是否曾经找到过通过动画块中的约束设置动画的解决方案。我使用它的方法是使用计时器或CADisplayLink来调整高度约束。
I don't think you're doing anything wrong, this seems to be the way that labels behave when you try to animate their height. I know I've wrestled with this problem in the past, and I can't remember if I've ever found a solution that works by animating the constraints in an animation block. The way I have gotten it to work is to use a timer or CADisplayLink to adjust the height constraint.
-(void)shrinkLabel {
self.constraintWhiteHeight.constant -= 1;
if (self.constraintWhiteHeight.constant >= secondaryHeight)
[self performSelector:@selector(shrinkLabel) withObject:nil afterDelay:.05];
}
编辑后:
虽然计时器方法有效,但它并不总是看起来很平滑,具体取决于您使用的速度和增量。另一种方法是使用较大的UIView(与电影中的黄色标签大小相同),内部较小的UILabel,对较大的视图具有centerX和centerY约束。然后,像往常一样使用animateWithDuration动画黄色视图:动画:
Although the timer method works, it doesn't always look smooth, depending on the speed and increments you use. Another way to do this is to use a large UIView (the same size as the yellow label in your movie) with a smaller UILabel inside that has centerX and centerY constraints to the larger view. Then, animate the yellow view as usual with animateWithDuration:animations:
-(void)shrinkLabel {
self.yellowViewHeightCon.constant = secondaryHeight;
[UIView animateWithDuration:5 animations:^{
[self layoutIfNeeded];
}];
}
这篇关于动画约束更改,定位动画但高度跳跃没有动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!