UIButton resize with animation - iphone

I'm creating a menu and I want the buttons to "pop" I guess on the screen. Basically I want to start at 0px dimensions and then go up to the full size of the buttons. I can animate the alpha and the position if I want to but can't do the dimensions and I think its because its an image on the button.
If I do a UIButtonTypeRoundRect you can see the button being animated behind the image but the image is static.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage:[UIImage imageNamed:#"settings.png"] forState:UIControlStateNormal];
button.frame = CGRectMake(20, 20, 0, 0);
button.alpha = 0;
[self.view addSubview:button];
CGRect frame = button.frame;
[UIView beginAnimations:#"button" context:nil];
[UIView setAnimationDuration:1];
button.alpha = 1;
frame.size.width += 53;
frame.size.height += 53;
button.frame = frame;
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
So the Alpha works but the resize doesn't. I've also played with stretchableImageWithLeftCapWidth to try and give it context or something but to no avail.
Cheers for your help.

Could you try using the following code instead?
button.transform = CGAffineTransformMakeScale(1.5,1.5);
button.alpha = 0.0f;
[UIView beginAnimations:#"button" context:nil];
[UIView setAnimationDuration:1];
button.transform = CGAffineTransformMakeScale(1,1);
button.alpha = 1.0f;
[UIView commitAnimations];
Your button should start slightly larger and then shrink back down. If this scales properly, just adjust the scalefactor before and after to suit.

Updated for Swift:
You can insert this in whatever IBAction you've got tied to a button to animate it when it's touched.
// animate button
// play with the scale (1.25) to adjust to your liking
yourButton.transform = CGAffineTransformMakeScale(1.25, 1.25)
yourButton.alpha = 0.0
UIView.beginAnimations("yourButton", context: nil)
// play with the animationDuration to adjust to your liking
UIView.setAnimationDuration(0.25)
yourButton.transform = CGAffineTransformMakeScale(1.0, 1.0)
yourButton.alpha = 1.0

Related

iOS translation and scale animation

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

UIView animateWithDuration interfering with other CGRectMake

I have a CGRectMake that used to jump an image to a different position
image.frane=CGRectMake( x,y,w,h);
Then I wanted to translate and scale a Label (on the same ViewController) to another position
CGPoint newCenter = CGPointMake(x,y);
[UIView animateWithDuration: 1.0
delay: 0
options: 0
animations:^{label.center = newCenter ; label.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.2, 0.2);}
completion:^(BOOL finished) {
label.transform = CGAffineTransformMakeScale(1.0, 1.0);
label.alpha = 0;
}
];
The problem I'm having is when I use the animateWithDuration the image doesn't move but the Label does. If I comment out the animation the image moves again. Am I doing something wrong?
try this bellow code...
[UIView animateWithDuration:1.0f animations:^{
imageView.frame = CGRectMake(newCenter.x, newCenter.y, imageView.frame.size.width, imageView.frame.size.height);
}];
Also you can move UIImageView or anything else with this bellow code... i use this code for scroll the UIScrollView when keyboard appear.. i add the code with your requirement..
UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0f];
imageView.frame = CGRectMake(newCenter.x, newCenter.y, imageView.frame.size.width, imageView.frame.size.height);
[UIView commitAnimations];
i hope this helpful to you...

UIButton image button with animation

I have a white image button. when I click, it should change into yellow button image by animating from Bottom to top and if I click yellow button image again it must animate top to bottom and change as white image button image.
This is what I tried:
float originalY = btn.frame.origin.y;
float originalH = btn.bounds.size.height;
[UIView animateWithDuration:3.0f delay:1.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
btn.frame = CGRectMake(btn.frame.origin.x, (originalY + originalH), btn.bounds.size.width, 0);
[btn setBackgroundImage:[UIImage imageNamed:#"yellowimg.png"] forState:UIControlStateNormal];
[btn setTitleColor:[[UIColor alloc]initWithRed:38.0/255.0 green:38.0/255.0 blue:38.0/255.0 alpha:1.0] forState:UIControlStateNormal];
}
completion:^(BOOL finished) {
}];
btn.frame = CGRectMake(btn.frame.origin.x, (originalY + originalH), btn.bounds.size.width, 0);
This method will make your button with height = 0.
If you want to curl (flip) your button and to have 'new' button which appeared from the first as I know you should use something like that
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:firstView cache:YES];
[firstView addSubview:secondView];
[UIView commitAnimations];

UIAnimation - Show UIView from button.frame.origin.y

I have a UIButton somewhere on my view. On touch event of button I making a UIView appear. The UIAnimation I have used make the view appear from top of window. But I want it to appear from button.frame.origin.y . Before touching the button the view is not visible. On touching the button view should start appearing from above position.
Here is the code :
-(IBAction) ShowInfowView:(id)sender{
CGRect rect = viewInfo.frame;
rect.origin.y = rect.size.height - rect.size.height+58.0;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.70];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
viewInfo.frame = rect;
[UIView commitAnimations];
}
This is how I am hiding the view again :
-(IBAction) HideInfoView:(id)sender{
CGRect rect = viewInfo.frame;
rect.origin.y = -rect.size.height;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.70];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
viewInfo.frame = rect;
[UIView commitAnimations];
}
In viewDidLoad I am doing the following :
CGRect rect = viewInfo.frame;
rect.origin.y = -rect.size.height;
viewInfo.frame = rect;
UPDATE:
Please see this example. Here view is appearing from top of screen. I want it to appear from button y axis. For that matter please consider button y position a bit upwards.
So you want a slide-in effect, but not from the top of the screen, just some arbitrary value?
One way to do it:
1) You should create a view that has the dimensions and position of your desired view AFTER animation finishes, we'll call it baseview.
2) Set this baseview property clipsToBounds to YES. This will make all subviews that are outside of the baseview's frame invisible.
3) Add your animating view as a subview of the baseview, but set the frame so it is invisible (by plcacing it above the baseview):
frame = CGRectMake(0, -AnimViewHeight, AnimViewWidth, AnimViewHeight);
4) Animate the animview frame:
//put this inside of an animation block
AnimView.frame = CGRectMake(0, 0, AnimViewWidth, AnimViewHeight);
EDIT:
Example:
//define the tags so we can easily access the views later
#define BASEVIEW_TAG 100
#define INFOVIEW_TAG 101
- (void) showInfo
{
//replace the following lines with preparing your real info view
UIView * infoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[infoView setBackgroundColor: [UIColor yellowColor]];
[infoView setTag: INFOVIEW_TAG];
//this is the frame of the info view AFTER the animation finishes (again, replace with real values)
CGRect targetframe = CGRectMake(100, 100, 100, 100);
//create an invisible baseview
UIView * baseview = [[UIView alloc] initWithFrame:targetframe];
[baseview setBackgroundColor: [UIColor clearColor]];
[baseview setClipsToBounds: YES]; //so it cuts everything outside of its bounds
[baseview setTag: BASEVIEW_TAG];
//add the nfoview to the baseview, and set it above the bounds frame
[baseview addSubview: infoView];
[infoView setFrame:CGRectMake(0, -infoView.bounds.size.height,
infoView.bounds.size.width, infoView.bounds.size.height)];
//add the baseview to the main view
[self.view addSubview: baseview];
//slide the view in
[UIView animateWithDuration: 1.0 animations:^{
[infoView setFrame: baseview.bounds];
}];
//if not using ARC, release the views
[infoview release];
[baseview release];
}
- (void) hideinfo
{
//get the views
UIView * baseView = [self.view viewWithTag: BASEVIEW_TAG];
UIView * infoView = [baseView viewWithTag: INFOVIEW_TAG];
//target frame for infoview - slide up
CGRect out_frame = CGRectMake(0, -infoView.bounds.size.height,
infoView.bounds.size.width, infoView.bounds.size.height);
//animate slide out
[UIView animateWithDuration:1.0
animations:^{
[infoView setFrame: out_frame];
} completion:^(BOOL finished) {
[baseView removeFromSuperview];
}];
}
I have done exactly what you're trying in my recent project.
The following steps should make this work:
1. In your viewDidLoad: you init your viewToFadeIn like this:
viewToFadeIn = [[UIView alloc] initWithFrame:CGRectMake(20,self.view.frame.size.height+10, self.view.frame.size.widh-40, 200)];
//its important to initalize it outside your view
//your customization of this view
[self.view addSubview:viewToFadeIn];
2.your ShowInfowView: Method should look like this:
` -(IBAction) ShowInfowView:(id)sender{
[UIView beginAnimations:#"fadeIn" context:NULL];
[UIView setAnimationDuration:0.25];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
viewToFadeIn.transform = CGAffineTransformMakeTranslation(0, -290);
//290 is in my case, try a little for your correct value
[UIView commitAnimations];
}
3.yourHideInfoView:` Method looks like this
-(IBAction) HideInfoView:(id)sender{
[UIView beginAnimations:#"fadeOut" context:NULL];
[UIView setAnimationDuration:0.25];
[UIView setAnimationDelegate:self];
viewToFadeIn.transform = CGAffineTransformMakeTranslation(0, 0);
[UIView commitAnimations];
}
EDIT:
4. animationFinishedMethod:
- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
if ([animationID isEqual:#"fadeIn"]) {
//Do stuff
}
if ([animationID isEqual:#"fadeOut"]) {
//Do stuff
}
}
SEE THIS
This should do the trick. Good luck
Your problem is not clear (for me).
What is this?
rect.origin.y = rect.size.height - rect.size.height+58.0;
Is 58 origin of your UIButton?
You should use sender.frame etc
Use blocks to animate like this
[UIView animateWithDuration:0.5f animations:^{
// Animation here
} completion:^(BOOL finished) {
// onComplete
}];
- (void) slideIn{
//This assumes the view and the button are in the same superview, if they're not, you'll need to convert the rects
//I'm calling the animated view: view, and the button: button...easy enough
view.clipToBounds = YES;
CGRect buttonRect = button.frame;
CGRect viewRect = CGRectMake(buttonRect.origin.x, buttonRect.origin.y + buttonRect.size.height, view.bounds.size.width, 0);
CGFloat intendedViewHeight = view.height;
view.frame = viewRect;
viewRect.size.height = intendedViewHeight;
[UIView animateWithDuration:.75 delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{
view.frame = viewRect;
}completion:nil];
}
This will cause the the view to appear to slide out from under the button. To slide the view back in, you just reverse the animations. If you wish to slide it up from the button, you'll need to make sure your starting 'y' is the 'y' value of the button (rather than the 'y' + 'height') and animate both the height and y values of the view that needs animating.

UIView beginanimations: subview shall not animate

Hi I have a UIView to which I add a UIButton in its initWithFrame: method like this:
UIButton * dropB = [UIButton buttonWithType:UIButtonTypeRoundedRect];
dropB.frame = CGRectMake(190, 22, 52, 22);
dropB.backgroundColor = [UIColor clearColor];
dropB.titleLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:11];
[dropB setTitle:#"DROP" forState:UIControlStateNormal];
[dropB addTarget:viewController
action:#selector(dropSelectedObject)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:dropB];
Then, as I try to animate the view with a resizing like this:
[UIView beginAnimations:#"MoveIt" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
self.dropButton.center = CGPointMake(self.dropButton.center.x + 80, self.dropButton.center.y -10);
self.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
self.center = CGPointMake(CENTER_X, CENTER_Y);
[UIView commitAnimations];
The button only gets translated to a new position which is the previous one (the original coordinates were relative to the view i guess). How can I make it translate to the point i specify?
Ok it was pretty simple (and stupid).
Since I needed the UIButton to remain at a fixed height I had to specify what space was 'flexible' while resizing. This can be done using the autoresizingMask property of an UIView this way:
dropB.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleBottomMargin;
and not calling anithing among the animation instructions