iOS翻译和比例动画

21

我正在开发UIButton动画,其中:

UIButton被设置在屏幕底部中心并缩小到小尺寸

_menuBtn.transform = CGAffineTransformMakeScale(0.1f, 0.1f);
当应用程序启动时,它应该随着其缩放或恢复到原始大小而移动到屏幕的左下角。
- (void)viewDidLoad
{
    [super viewDidLoad];

    _menuBtn.frame = CGRectMake(160, 513, 30, 30); 
    _menuBtn.superview.frame = CGRectMake(160, 513, 30, 30);

    _menuBtn.transform = CGAffineTransformMakeScale(0.1f, 0.1f);
    NSLog(@"_menuBtn: %@ ; _menuBtn.superview: %@", _menuBtn, _menuBtn.superview);
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDuration:5];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    CGAffineTransform scaleTrans  = CGAffineTransformMakeScale(1.0f, 1.0f);
    CGAffineTransform lefttorightTrans  = CGAffineTransformMakeTranslation(-200.0f,0.0f);
    _menuBtn.transform = CGAffineTransformConcat(scaleTrans, lefttorightTrans);
    [UIView commitAnimations];

}

问题

当动画开始时,按钮从屏幕右下角开始移动,而不是在底部中心,这是它应该出现的位置。有什么帮助吗?

日志结果

NSLog(@"%@", _myBtn);

2013-08-14 09:22:38.913 GJCoolNavi[339:c07] <UIButton: 0x813ea30; frame = (0 0; 0 0); opaque = NO; autoresize = TM+BM; layer = <CALayer: 0x813eaf0>>

这是在执行动画之前的状态...动画执行后的结果如下:

2013-08-14 09:30:25.719 GJCoolNavi[612:c07] <UIButton: 0x71206d0; frame = (160 294; 0 0); opaque = NO; autoresize = TM+BM; animations = { transform=<CABasicAnimation: 0x7536a80>; position=<CABasicAnimation: 0x7537dd0>; }; layer = <CALayer: 0x7120790>>

1
我的第一个想法可能与主题无关,但为什么您没有像苹果在iOS4或更高版本中建议的那样使用基于块的动画呢? - holex
我也是第一个想到的。在我的答案中,显然还是不起作用。仍在努力弄清楚发生了什么以及为什么。 - Fogmeister
4个回答

28

为什么不这样做...

_menuBtn.transform = CGAffineTransformMakeScale(0.1, 0.1);

[UIView animateWithDuration:5.0
options:UIViewAnimationOptionCurveEaseOut
animations:^(){
    _menuBtn.transform = CGAffineTransformMakeScale(1.0, 1.0);
    _menuBtn.center = self.view.center;
}
completion:nil];

我建议您避免使用 transform 进行物品移动,改为更改帧。 编辑
- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // for convenience I'm pulling these values out in to variables.
    float buttonWidth = _menuBtn.frame.size.width;
    float buttonHeight = _menuBtn.frame.size.height;
    float viewWidth = self.view.frame.size.width;
    float viewHeight = self.view.frame.size.height;

    // set the button frame to be the bottom center
    // note you shouldn't have to do this as Interface Builder should already place it there.
    // place the button in the horizontal center and 20 points from the bottom of the view.
    _menuBtn.frame = CGRectMake((viewWidth - buttonWidth) * 0.5, viewHeight - buttonHeight - 20, buttonWidth, buttonHeight);

    // scale the button down before the animation...
    _menuBtn.transform = CGAffineTransformMakeScale(0.1, 0.1);

    // now animate the view...
    [UIView animateWithDuration:5.0
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         _menuBtn.transform = CGAffineTransformIdentity;
                         _menuBtn.frame = CGRectMake(viewWidth - buttonWidth - 20, viewHeight - buttonHeight - 20, buttonWidth, buttonHeight);
                     }
                     completion:nil];
}

请尝试这个方法,并告诉我结果如何。

它的结果为null: '2013-08-13 18:42:31.797 GJCoolNavi[11313:c07] (null)' - Jrey Quiros
menuBtn.superview是什么?按钮是否在单独的视图中,还是只在主视图中? - Fogmeister
我已经尝试了你的代码,它的作用就是从底部中心向上移动。 - Jrey Quiros
你已经把改变框架的东西留下了吗?你仍然需要改变框架。不,这不是因为恒等变换。 - Fogmeister
1
这是由于使用自动布局导致的...非常感谢Fogmeister的帮助。 - Jrey Quiros
显示剩余19条评论

7

这解决了一个类似的问题。

应用一个 (UIButton).imageView 动画。

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGAffineTransform scaleTrans  = CGAffineTransformMakeScale(1.0f, 1.0f);
CGAffineTransform lefttorightTrans  = CGAffineTransformMakeTranslation(-200.0f,0.0f);
_menuBtn.imageView.transform = CGAffineTransformConcat(scaleTrans, lefttorightTrans);
[UIView commitAnimations];

谢谢!这是唯一一个对我有效的解决方案,而且它完美地运行着! - Serzhas

2

这种现象表明您的按钮原始框架是错误的,可能是由于其自动调整大小导致的。在开始动画之前,请将其框架设置为底部中心。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    _menuBtn.superview.frame = CGRectMake(0, 513, 320, 30); // This is a quick and dirty solution to make sure your button's superview is in the right place. You probably don't want to do this and are more likely to review your view hierarchy.
    _menuBtn.frame = CGRectMake(145, 0, 30, 30); // Set the frame to the bottom center, please ensure that _menuBtn's transform hasn't been changed before this step
    _menuBtn.transform = CGAffineTransformMakeScale(0.1f, 0.1f);
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDuration:5];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    CGAffineTransform scaleTrans  = CGAffineTransformMakeScale(1.0f, 1.0f);
    CGAffineTransform lefttorightTrans  = CGAffineTransformMakeTranslation(-200.0f,0.0f);
    _menuBtn.transform = CGAffineTransformConcat(scaleTrans, lefttorightTrans);
    [UIView commitAnimations];
}

我按照您建议的方式进行了设置,将其框架设置为底部中心...但是当应用_CGAffineTransformMakeTranslation_时,按钮仍然从右下角开始动画而不是从底部中心开始... - Jrey Quiros
我能想到的原因可能是您的按钮的父视图位置也不正确。在动画块之前,请检查您的按钮及其父视图的框架。您可以在 _menuBtn.transform = CGAffineTransformMakeScale(0.1f, 0.1f); 下方打印日志,例如:NSLog(@"_menuBtn: %@ ; _menuBtn.superview: %@", _menuBtn, _menuBtn.superview); - liuyaodong
啊,问题找到了!你的按钮的父视图的origin是{160, 513},这可能是屏幕底部中心位置。但是你的按钮的origin是{158.5, 511.5},这是相对于它的父视图的位置,换句话说,它是屏幕右下角。请在动画块之前尝试这个:_menuBtn.superview.frame = CGRectMake(0, 513, 320, 30); _menuBtn.frame = CGRectMake(145, 0, 30, 30); 我会更新我的答案。 - liuyaodong
使用您建议的代码,_menuBtn 的框架为 (158.5 -6.5; 3 3),其父视图为 (0 513; 320 30)... 但按钮仍从右下角开始动画。 - Jrey Quiros
@Fogmeister 我有所怀疑。因为他得到了日志 "_menuBtn.superview: <UIView: 0x8084380; frame = (160 513; 30 30); "。self.view不可能是那个框架。所以我认为他的视图层次结构必须更加复杂。 - liuyaodong
显示剩余6条评论

0

我已经使用了你的代码,它从底部中心移动到底部左侧非常完美。可能是你的父视图的矩形不正确,请检查一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接