I've got a Selected-state and a Normal-state for an UIButton that both are UIImages. When a button is touched, I'd like it to hit the selected-state and then animate back to the normal-state over the period of one second. I've set the following animation when the UIButton* btn is pressed, but it just switches right back to deselected state again. How should I go about achieving this?
[btn setSelected:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0f];
[btn setSelected:NO];
[UIView commitAnimations];
Cheers
Nik
Since selected is not an animatable property, that won't work (as you've found out). My solution would be to have the selected state of the btn be in a separate UIImageView directly below the button in the exact same location. Then in the action for tapping the button:
- (void) tapButton:(UIButton *)btn {
btn.alpha = 0;
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationDelegate:[UIApplication sharedApplication]];
[UIView setAnimationDidStopSelector:#selector(endIgnoringInteractionEvents)];
btn.alpha = 1;
[UIView commitAnimations];
}
Note I also added the begin/endIgnoringInteractionEvents calls so the user can't tap on the button while it's fading back to its normal state. If you want to allow that, replace the begin/end calls with [UIView setAnimationBeginsFromCurrentState];
Related
I wanted to change the animation that occurs on a navigationControllers toolbar when the method setToolbarHidden is called. By default, when you set Hidden to YES and animation to YES, the toolbar simply drops off the screen. I'd like it to slide off the screen from left to right (much like when you hit the back button on a navbar and the previous view controller reasserts itself on the screen). Is this possible?
This isn't going to be perfect but it might be possible with something like this:
self.navigationController.toolbarHidden = NO;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
CGRect frame = self.navigationController.toolbar.frame;
frame.origin.x = -1*frame.size.width;
self.navigationController.toolbar.frame = frame;
[UIView commitAnimations];
- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context {
self.navigationController.toolbarHidden = YES;
}
I filed a bug report and it appears, unfortunately, there isn't a way to do this until Apple adds the feature themselves.
I am trying to build a custom share panel with buttons.
This is how it appears before being clicked.
This is how it appears after.
I know that may be complicated, but I need the steps to accomplish this.
The images show the mock-ups of the panel.
You just think complicated. It is not complicated; all you need is a view on the main window with this arrow custom button, when click it just move it from bottom to top.
I found the solution.
Create the user interface.
Link the user interface with IBoutlets and IBActions.
Animate the UIView item with buttons.
-(IBAction) openPanelBtnPressed:(id)sender{
CGPoint wpos = self.panel.frame.origin ;
if(wpos.x == 0 && wpos.y ==133){
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationBeginsFromCurrentState:YES];
self.panel.frame=CGRectMake(0.0,330, 76, 368);
self.panel.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
UIImage * imgOpenPanelBtn = [UIImage imageNamed:#"up.png"];
[self.btnOpenPanel setImage:imgOpenPanelBtn forState:UIControlStateNormal];
}else {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationBeginsFromCurrentState:YES];
self.panel.frame=CGRectMake(0.0, 133.0, 76, 368);
self.panel.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
UIImage * imgOpenPanelBtn = [UIImage imageNamed:#"down.png"];
[self.btnOpenPanel setImage:imgOpenPanelBtn forState:UIControlStateNormal];
}
}
The result is this one: http://www.youtube.com/watch?v=6zoZKjbZAps.
You can find the explanation in Arabic on my blog.
You can download the project.
Is it possible to make textfield come from above to down in an animated way when a button is pressed?
Yes. You must chnage the frame of the UITextField inside an animation block. Something like this. Assuming, for example, that the Y origin of the text field before pressing the button is 0.0f (top of its container).
- (void) buttonPressed {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: <desired_animation_duration_in_seconds> ];
CGRect aFrame = _myTextField.frame;
aFrame.origin.y = <desired_y_coord>;
_myTextField.frame = aFrame;
[UIView commitAnimations];
}
I am adding some basic animation to a card game I'm working on. (My first iPhone app.)
I am creating a custom UIView class "AnimationContainer", which flips from image1 to image2, while moving from rect1 to rect2. My ultimate intention is to have up to four of these containers doing their transitions simultaneously.
The problem I'm having is that the animation isn't showing image1... so only the last half of the flip transition appears.
However, if I reset the animation first by touching Reset, then everything works perfectly. In other words, if I press Flip again and again, I only get half the transition... but if I press Reset first, then everything works perfectly for one flip.
So, how can I get the animation to reset itself correctly?
Below is the code, a screenshot, and here's a link to the complete: Project Zip File 700k.
- (void)displayWithImage1 { //RESET button calls this
self.frame = rect1;
[image2 removeFromSuperview];
[self addSubview:image1];
[self setNeedsDisplay]; //no help: doesn't force an update before animation
}
- (void)runTheAnimation { //FLIP button calls this
[self displayWithImage1]; //<---this is what the reset button calls
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:transition forView:self cache:NO];
self.frame = rect2;
[image1 removeFromSuperview];
[self addSubview:image2];
[UIView commitAnimations];
}
Thanks!
You need a drawing loop to pass in order to redraw the view before performing the animation. This code is an example of "draw this, and when the next event loop comes around, do this other thing." It's not uncommon to do this in UI code. Your first work-around is attempting the same thing, but in a much more complicated way.
- (void)_runTheAnimation {
// Moved here from -runTheAnimation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:transition forView:self cache:NO];
self.frame = rect2;
[image1 removeFromSuperview];
[self addSubview:image2];
[UIView commitAnimations];
}
- (void)runTheAnimation { //FLIP button calls this
[self displayWithImage1];
[self performSelector:#selector(_runTheAnimation) withObject:nil afterDelay:0.0];
}
Is there a way to make a custom animation when clicking on an iPhone button? I would like something like the App Store button - it shows the price, and then when you click on it, it changes color and the text changes to buy now, then when you click it again, it completes the purchase.
The UIViewAnimationTransition only contains a few values which don't provide the full functionality. Is it possible to do something like this but with the animation:
- (IBAction) changeButtonDisplay:(id)sender {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.8];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:purchaseButton cache:NO]; //the built in UIViewAnimationTransition values don't provide enough flexibility
[purchaseButton setTitle:#"Buy Now" forState:UIControlStateNormal];
[purchaseButton setBackgroundColor:[UIColor greenColor]];
[purchaseButton addTarget:self action:#selector(purchaseItems:) forControlEvents:UIControlEventTouchUpInside];
[UIView commitAnimations];
}
This code works and will display the proper transition and allow for the second click to do the proper action, but the title and color changes instantly, not in a smooth animation. Is it possible to do such an animation easily, of do I have to create a UIButton subclass and do the animation "manually"? If so, what method would I have to override?
Rather than just changing the title and target, etc of the button, have two separate buttons that do each action and look different. Then when you press the button, call a method that removes the current button from its super view and adds the new button to the view in its place. Wrap that up in some UIView animation block and you should get your animation.
Also, for this to work, you'll need to set the animation transition on the superview of the button. So it might be handy to have a 'container view' as it may be and then add you buttons as subviews of that.
Pseudo code might look something like so:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.8];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:buttonConteinerView cache:NO]; //the built in UIViewAnimationTransition values don't provide enough flexibility
[purchaseButton retain];
[purchaseButton removeFromSuperView];
[buttonContainerView addSubview:secondPurchaseButton];
[UIView commitAnimations];
A Standard UIView will do what you want. UIView's backgroundColor is an animatable property.
I would make own "button" by subclassing UIView OR alternatively subclass a UIButton and add subviews to it. (note: UIButtons were a pain about this in 2.2, not sure in 3.0)
You need a UILabel for each text state:
UILabel *textForStateOne;
UILabel *textForStateTwo;
And you can change the background color of the parent view.
So then you make a method in your new button class:
-(void)toggleState{
myState = !myState;
if(myState){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.8];
[textForStateOne setAlpha:1.0]
[textForStateTwo setAlpha:0.0]
[self setBackgroundColor:[UIColor greenColor]];
[UIView commitAnimations];
} else{
//do the opposite here
}
}
UIView *btnView4=button;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:btnView4 cache:YES];
[UIView commitAnimations];``