如何在调整UIView大小时制作动画

Ida*_*dan 17 iphone cocoa-touch core-animation uiview ios4

我在网上看到了一些材料,但仍然无法到达我想要的地方.我需要向下调整我的视图,使其高度更大.

到目前为止,这是我的代码.这里发生的事情是,不是我的视图调整大小,它只是改变了它的位置.如果我将proprty而不是"bounds.size"更改为"transform.scale.y",它会更好一些,只是这次它会向上和向下扩展视图,而不仅仅是向下扩展.

另一件事我不是:这些键只是CALayer属性吗?在哪里可以找到这些键的列表?

我真的很感激这里的帮助.谢谢!

int x = self.btnHead.frame.origin.x;
int y = self.btnHead.frame.origin.y;
int height = self.btnHead.frame.size.height;
int width = self.btnHead.frame.size.width;


CABasicAnimation *resizeAnimation = [CABasicAnimation animationWithKeyPath:@"bounds.size"];
[resizeAnimation setToValue:[NSValue valueWithCGSize:CGSizeMake(width,height+50)]];
resizeAnimation.fillMode = kCAFillModeForwards;
resizeAnimation.removedOnCompletion = NO;

CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = [NSArray arrayWithObjects:resizeAnimation,nil];
animationGroup.removedOnCompletion = NO;
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.removedOnCompletion=NO;
animationGroup.duration = 0.1;

[self.btnHead.layer addAnimation:animationGroup forKey:@"animations"];
Run Code Online (Sandbox Code Playgroud)

编辑:按要求发布我的第一个代码 - 这只会改变我的视图大小,但无论我输入的持续时间都不会动画.

    int x = self.btnHead.frame.origin.x;
    int y = self.btnHead.frame.origin.y;
    int height = self.btnHead.frame.size.height;
    int width = self.btnHead.frame.size.width;


    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:10];
    CGRect rect = CGRectMake(x,y,width ,height+BUTTON_HEIGH*2);

    self.btnHead.frame = rect;

    [UIView commitAnimations];
Run Code Online (Sandbox Code Playgroud)

Nat*_*ror 53

动画frame属性可能会有问题,但只要transform是标识(也就是说,您没有更改它),它应该可以正常工作.我刚刚测试了以下代码,它按预期工作:

[UIView animateWithDuration:.1f animations:^{
  CGRect theFrame = myView.frame;
  theFrame.size.height += 50.f;
  myView.frame = theFrame;
}];
Run Code Online (Sandbox Code Playgroud)

同样,如果您transform随时更改了该属性,则无法按预期工作.对于此动画的更加防弹版本,您需要bounds像尝试使用Core Animation一样为该属性设置动画.但是你仍然不需要放入Core Animation.

这里要理解的重要一点是它boundscenter属性之间的关系.所有仿射变换(平移,缩放或旋转)都需要一个参考点来执行变换.在UIView这是center重点的情况下.CALayer允许您通过anchorPoint属性移动参考点,但在这种情况下我们不需要担心.

视图在两个方向上缩放的原因是缩放操作发生在center.最简单的方法是将center y移动高度增量的一半.像这样:

myView.contentMode = UIViewContentModeRedraw;
[UIView animateWithDuration:.4f animations:^{
  CGRect theBounds = myView.bounds;
  CGPoint theCenter = myView.center;
  theBounds.size.height += 50.f;
  theCenter.y += 25.f;
  myView.bounds = theBounds;
  myView.center = theCenter;
}];
Run Code Online (Sandbox Code Playgroud)

最后的考虑是强制视图在bounds更改时重绘.出于性能原因,更改视图时不会重绘视图bounds.但是,当您更改frame属性时(它又是属性的另一个怪癖frame),它会重新绘制.要强制重做bounds更改,您需要设置contentMode我在上一个代码段的第一行中所做的操作.您可能希望在动画结束后将其设置回来,但这取决于您.这也是您的C​​ore Animation版本仅更改位置而不是大小的原因.在运行动画之前,您需要在代码中使用此行:

self.btnHead.layer.needsDisplayOnBoundsChange = YES;
Run Code Online (Sandbox Code Playgroud)

我希望这一切都有道理.首先frame,boundscenter属性可能有点令人困惑.

  • `frame`是一个便利属性(更容易布局视图),它描述了视图在其父坐标空间中的矩形.永远不会存储`frame`值.它是从`bounds`和`center`计算出来的.所以当你改变`frame`时,你实际上是在改变`bounds`和`center`.`bounds`描述了视图在其自己的坐标空间中的边界矩形(这就是它的原点通常为{0,0}的原因),`center`描述了视图在其父坐标空间中的位置.因此,这两个代码示例实际上完全相同. (4认同)

Ida*_*dan 10

btnHead.clipsToBounds=YES
Run Code Online (Sandbox Code Playgroud)

解决了这个问题.不确定为什么.


tas*_*oor 8

你不能只改变UIView动画块中的帧.看起来在这种情况下不需要CABasicAnimation.

[UIView beginAnimations:@"resize_animation" context:NULL];
// set your duration. a long duration is better to debug
// 0.1 is really short to understand what is going wrong
[UIView setAnimationDuration:2]; 

btnHead.frame = newFrame;

[UIView commitAnimations];