21

I'm working on UIButton animation where:

The UIButton is set in the bottom center of the screen and scaled to a small size

_menuBtn.transform = CGAffineTransformMakeScale(0.1f, 0.1f);

When the app starts it should be moving to the bottom left side of the screen as it scales or grow to its original size.

- (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];

}

problem

When the animation starts the button starts moving from the bottom right side of the screen and not in the bottom center where it is and should be. Any help ?

Log Result

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>>

thats before doing the animation...and the result after the animation is:

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>>
Fogmeister
  • 76,236
  • 42
  • 207
  • 306
Jrey Quiros
  • 233
  • 1
  • 3
  • 10
  • 1
    my first thought might be irrelevant for the topic, but why haven't you used block-based animation as the Apple recommends on iOS4 or above? – holex Aug 14 '13 at 07:48
  • First thing I thought too. It's in my answer, apparently it still doesn't work. Still trying to work out what is happening and why. – Fogmeister Aug 14 '13 at 08:01

4 Answers4

28

Why don't you do this...

_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];

I'd avoid moving stuff using a transform. Change the frame instead.

EDIT

- (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];
}

Try this and let me know what happens.

Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • I've tried the code but what it does is it starts from the top left of the screen towards the bottom center of the screen. what my code suppose to do is that it should move from the bottom center towards the bottom left of the screen. – Jrey Quiros Aug 13 '13 at 10:34
  • i created the button in the storyboard. and placed it in the bottom center of the screen – Jrey Quiros Aug 13 '13 at 10:36
  • Nothing, if you use them properly. But it gets confusing (case in point) especially when you ask the button where it is. Actually... please print the frame of the button before the animation. – Fogmeister Aug 13 '13 at 10:37
  • i didn't get you..what do you mean by printing the frame of the button ?sorry i'm new to this stuff. – Jrey Quiros Aug 13 '13 at 10:39
  • it results to null: '2013-08-13 18:42:31.797 GJCoolNavi[11313:c07] (null)' – Jrey Quiros Aug 13 '13 at 10:43
  • OK, try `NSLog(@"%@", _myBtn);` "null" is not helpful. And pleaee put it in the question. Doing this in comments is hard to read. – Fogmeister Aug 13 '13 at 10:44
  • It is as I thought. You are getting confused by using transforms. The frame of the button is (0,0,0,0). When you do ... `_menuBtn.transform = CGAffineTransformMakeScale(0.1, 0.1);` you are removing any translation you have applied to the button and so it is moving to its frame which is top left. If you stop using transforms to move stuff around the screen then you get rid of this confusion and you wouldn't have this problem. – Fogmeister Aug 14 '13 at 06:56
  • Please can you post every place where you change the transform of the button. – Fogmeister Aug 14 '13 at 06:56
  • What is menuBtn.superview? Is the button in a separate view or is the button just in the main view? – Fogmeister Aug 14 '13 at 07:42
  • the button just in the main view – Jrey Quiros Aug 14 '13 at 07:47
  • You shouldn't be setting the frame of the main view. Remove the line `menuBtn.spuerView.frame = ...` – Fogmeister Aug 14 '13 at 07:48
  • removing the `menuBtn.superview.frame ..` still has no effects..and still the animatino is not starting at the bottom center – Jrey Quiros Aug 14 '13 at 07:56
  • i've tried your code and what it does is just it moves upward from the bottom center. – Jrey Quiros Aug 14 '13 at 08:03
  • OK, changed again. Just realised that you're doing this in view did load and should really be in viewDidAppear. – Fogmeister Aug 14 '13 at 08:07
  • tried the code and yes it starts from the center but it moves toward the right side, which is ok....but, wheres the scale animation ? – Jrey Quiros Aug 14 '13 at 08:25
  • OK, that's coming next... OK, I added the scale in now. – Fogmeister Aug 14 '13 at 08:30
  • it just scale to its original size in the bottom center..its not moving... it may be cause by `CGAffineTransformIdentity` – Jrey Quiros Aug 14 '13 at 08:36
  • Have you kept in the stuff to change the frame? You still need to change the frame. And no, it isn't because of the identity transform. – Fogmeister Aug 14 '13 at 08:37
  • i tried `CGAffineTransformIdentity` after setting the button's frame and it resulted to a button moving with a curve path from the bottom right side to the bottom center while it scales up to its original size – Jrey Quiros Aug 14 '13 at 08:40
  • OK, I give up now. I've taken the code above and copied it into a project and it works perfectly. This code works, the button starts in the bottom center and is tiny. It then animates over 5 seconds and moves to the bottom right and grows until it is full size. – Fogmeister Aug 14 '13 at 08:42
  • did you use storyboard in making the button ?or just created it in the code ? – Jrey Quiros Aug 14 '13 at 08:44
  • I used storyboard. Are you using Auto Layout in the storyboard? If you are then this would cause an issue with the animation and you need to turn Auto Layout off (in the properties pane). – Fogmeister Aug 14 '13 at 08:44
  • 1
    and that's it..it's due to using auto layout...thank you so much for the help Fogmeister – Jrey Quiros Aug 14 '13 at 08:49
  • We got there in the end :) No worries. Rule 4 of using AutoLayout. You can't update frames directly. – Fogmeister Aug 14 '13 at 08:51
7

This has solved a similar problem.

Apply a (UIButton).imageView Animation.

[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];
SaintHawk
  • 71
  • 1
  • 1
2

This phenomenon indicates that your button's original frame is wrong, probably because of its auto-resizing. Try setting its frame to the bottom center before you start the animation.

- (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];
}
liuyaodong
  • 2,547
  • 18
  • 31
  • i follow what you've suggested, by setting its frame to the bottom center..but still when applying _CGAffineTransformMakeTranslation_ the button still start animating from the bottom right side and not from the bottom center... – Jrey Quiros Aug 14 '13 at 06:52
  • The reason I could think of may be that your button's superview is also at the wrong position. Please check your button and its superview's frames before animation block. You can print the log just below the `_menuBtn.transform = CGAffineTransformMakeScale(0.1f, 0.1f);`, like: `NSLog(@"_menuBtn: %@ ; _menuBtn.superview: %@", _menuBtn, _menuBtn.superview);` – liuyaodong Aug 14 '13 at 07:09
  • i've set the button's superview but still no effect..after i've set the superview, this is what logs shows: `2013-08-14 15:16:52.686 GJCoolNavi[12708:c07] _menuBtn: > ; _menuBtn.superview: >` i've print the log before the animation starts. – Jrey Quiros Aug 14 '13 at 07:18
  • Ah, that's the problem! Your the `origin` of your button's superview is {160, 513} which is probably your bottom center position of your screen. But your button's `origin` is {158.5, 511.5}, which is a position relative to its superview, in other word, it's the bottom right of the screen. Please try this: `_menuBtn.superview.frame = CGRectMake(0, 513, 320, 30); _menuBtn.frame = CGRectMake(145, 0, 30, 30);` before the animation block. And I will update my answer. – liuyaodong Aug 14 '13 at 07:30
  • using the code you've suggested the _menuBtn frame is `(158.5 -6.5; 3 3)` and the superview is `(0 513; 320 30)`..and still the button starts animating from the bottom right side. – Jrey Quiros Aug 14 '13 at 07:39
  • @Fogmeister: any suggestions or libraries that can be use with animations ? – Jrey Quiros Aug 14 '13 at 07:47
  • Try commenting the animation block and run your code. Is your button at the bottom center? – liuyaodong Aug 14 '13 at 07:49
  • yes. i did use storyboard in creating and setting the button. – Jrey Quiros Aug 14 '13 at 07:52
  • Try my updated answer. Place the code in `-viewWillAppear:` and set your superview.frame.origin.x to 0. – liuyaodong Aug 14 '13 at 07:58
  • but the `menuBtn.superView` is the main view. i.e. `self.view`. Why does he need to change it at all? – Fogmeister Aug 14 '13 at 07:59
  • @Fogmeister I doubt it. Because he got the log "_menuBtn.superview: – liuyaodong Aug 14 '13 at 08:02
0

I have used your code and its moving from bottom center to to bottom left perfectly. Might be your superview isn't in proper rect. Please check.

Krishna Kumar
  • 1,652
  • 9
  • 17