I started trying to recreate the buy button from the app store which requires a 2-stage click to buy something. I to animate the button expanding. So far I have this
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
sender.autoresizesSubviews = NO;
sender.clipsToBounds = NO;
sender.frame = CGRectMake(63,326,200,37);
[UIView commitAnimations];
which just causes the button to become larger, it doesn't animate at all. Have I done something wrong or has anyone else implemented this type of button behaviour?
EDIT:
- (IBAction) buyButtonAction: (UIButton *) sender {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationDelay:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
sender.clipsToBounds = NO;
sender.frame = CGRectMake( CGRectGetMinX( sender.frame) - 30, CGRectGetMinY(sender.frame), 200, 37);
[sender setTitle:#"Touched Touched Touched" forState:UIControlStateNormal];
[UIView commitAnimations];
}
Are you targeting an iOS that doesn't support Blocks?
I've implemented a "button animates on touch" using the following nauseatingly simple code.
[UIView animateWithDuration:0.5 animations:^{
self.navigationItem.rightBarButtonItem.title = #"Quoting...";
}];
Alternatively, this code seems to work as well to animate a button on touch, if you can't support blocks (it also includes the blocks commented out if you go that route):
-(IBAction) clicked:(UIButton*)sender{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
//[UIView animateWithDuration:2.5 animations:^{
sender.autoresizesSubviews = NO;
sender.clipsToBounds = NO;
sender.frame = CGRectMake(63,326,200,37);
//sender.frame = CGRectMake( CGRectGetMinX( self.theButton.frame) - 100, CGRectGetMinY(self.theButton.frame), 300, 40);
//[sender setTitle:#"Touched Touched Touched" forState:UIControlStateNormal];
//}];
Related
I am new in ios development, Now i am doing some animation on my application.In my application has one menu on the bottom of main view and have two button one for hide the menu and other for show the menu .My needs is the show and hide function of menu is working like
the [self presentModalViewController:menuView animated:YES]; and [self dismissModalViewControllerAnimated:YES]; function(ie. click the show button ,pop the menuView from the bottom of main view and click the hide button ,move down the menuView ) . I know the basic animation like:
[UIView beginAnimations:#"ShowHideView" context:nil];
[UIView setAnimationCurve:UIViewAnimationOptionOverrideInheritedCurve];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[menuView setAlpha:0];
[UIView commitAnimations];
If any body know ,please help me.
When you tap showMenuView, do as following,
- (IBAction)showView:(id)sender
{
[self.view addSubview: menuView];
CGRect rect = menuView.frame;
rect.origin.y = 480;
menuView.frame = rect;
[UIView beginAnimations:#"ShowView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
rect.origin.y = 0;
menuView.frame = rect;
[UIView commitAnimations];
}
And to hide,
- (IBAction)hideView:(id)sender
{
CGRect rect = menuView.frame;
[UIView beginAnimations:#"HideView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
rect.origin.y = 480;
menuView.frame = rect;
[UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
[menuView removeFromSuperview];
}
hi
when certain events occur, I call a number of methods (unlocked trophies in a game) they do appear and disappear a sub-view.
Crash (rightly) occurs when these events occur simultaneously and overlap.
How do I make sure that " wait your turn :) "?
thanks
-(void)trofeiLaunch:(int)x {
CGRect loseFrame = CGRectMake(0, 0, 480, 320);
TrofeoView = [[UIView alloc] initWithFrame:loseFrame];
TrofeoView.alpha = 0.0;
[UIView beginAnimations:nil context:self];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[UIImageView setAnimationDelegate:self];
TrofeoView.alpha = 1.0;
[UIView setAnimationDidStopSelector:#selector(bridgeTrofei)];
[UIView commitAnimations];
[self.view addSubview:TrofeoView];
[TrofeoView release];
....
}
-(void)bridgeTrofei {
TrofeoView.alpha = 1.0;
[UIView beginAnimations:nil context:self];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
TrofeoView.alpha = 0.0;
[UIView commitAnimations];
[self performSelector:#selector(deleteTrofei) withObject:self afterDelay:1.0];
}
-(void)deleteTrofei {
[TrofeoView removeFromSuperview];
NSLog(#"delete");
}
Crash (rightly) occurs when these events occur simultaneously and overlap.
How do I make sure that " wait your turn :) "?
thanks
If the second animation starts before the first animation is complete, TrofeoView will get reassigned and you will lose the earlier reference. You also flout memory management rules when you release TrofeoView in 'trofeiLaunch:` method. You use this variable again later with having taken ownership. You should only release an object if you are done with it which you are not.
I think the most important thing going down this path is to make sure that three methods refer to the correct object. First one is ok by default so you need to handle the next two. I have modified your code to do that.
- (IBAction)start {
animatingView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
animatingView.backgroundColor = [UIColor greenColor];
animatingView.alpha = 0.0;
[UIView beginAnimations:#"Trophy Display" context:animatingView];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[UIImageView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
animatingView.alpha = 1.0;
[UIView commitAnimations];
[self.window addSubview:animatingView];
}
- (void)animationDidStop:(NSString*)animationID finished:(NSNumber*)finished context:(void *)context {
if ( [animationID isEqualToString:#"Trophy Display"] ) {
UIView *aView = (UIView *)context;
[UIView beginAnimations:nil context:aView];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
aView.alpha = 0.0;
[UIView commitAnimations];
[self performSelector:#selector(finishAnimation:) withObject:aView afterDelay:1.0];
}
}
- (void)finishAnimation:(UIView*)aView {
[aView removeFromSuperview];
[aView release];
}
I pass the view via context to the second method and withObject: part to the third method. I am hoping the code is self explanatory. Let me know if you don't get this.
Next point is about whether this is the right way. Can't you manage this using an array? Push only if there is no view in display.
I am trying to fade in a UIView as a subview of my main view. The UIView I am trying to fade in has the dimensions of 320x55.
I setup the view and a timer;
secondView.frame = CGRectMake(0, 361, 320, 55);
secondView.alpha = 0.0;
[self.view addSubview:secondView];
[NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:#selector(fadeView) userInfo:NO repeats:NO];
The timer triggers the following code;
secondView.alpha = 1.0;
CABasicAnimation *fadeInAnimation;
fadeInAnimation = [CABasicAnimation animationWithKeyPath:#"opacity"];
fadeInAnimation.duration = 1.5;
fadeInAnimation.fromValue = [NSNumber numberWithFloat:0.0];
fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0];
[fadeInAnimation setDelegate:self];
[secondView.layer addAnimation:fadeInAnimation forKey:#"animateOpacity"];
My secondView is connected in Interface Builder and responds to other messages but I can't see anything happening on screen.
Can anyone please help me figure out what's going on here?
Thanks,
Ricky.
In reply to a following recommendation:
I'm a bit unsure here. Initially I put this code in (because I see secondView as an instance of UIView?):
[secondView beginAnimations:nil context:NULL];
[secondView setAnimationDuration:0.5];
[secondView setAlpha:1.0];
[secondView commitAnimations];
I then tried your suggestion which didn't produce warnings or errors, but it still does brings nothing to the surface:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[secondView setAlpha:1.0];
[UIView commitAnimations];
Thanks! Ricky.
You should be able to do this a bit simpler. Have you tried something like this?
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[secondView setAlpha:1.0];
[UIView commitAnimations];
it seems to me that one thing you're missing is that your view may already have an alpha of 1.0. make sure the alpha is 0 (or whatever you desire it to be) prior to the animation call.
i prefer to use block animations for this. it's cleaner and more self-contained.
secondView.alpha = 0.0f;
[UIView animateWithDuration:1.5 animations:^() {
secondView.alpha = 1.0f;
}];
This won't answer your question if you insist on using CoreAnimations, but for iPhoneOS it's much easier to use animation blocks for UIView animations.
secondView.alpha = 0.0f;
[UIView beginAnimations:#"fadeInSecondView" context:NULL];
[UIView setAnimationDuration:1.5];
secondView.alpha = 1.0f;
[UIView commitAnimations];
Also, you can invoke a delegate in delayed time with
[self performSelector:#selector(fadeView) withObject:nil afterDelay:0.5];
Here is also a good alternative with many options and easy to use.
[secondViewController.view setAlpha:0.0];
[UIView animateWithDuration:1.5
delay:0.0
options:UIViewAnimationOptionCurveEaseIn // See other options
animations:^{
[secondViewController.view setAlpha:1.0];
}
completion:^(BOOL finished) {
// Completion Block
}];
Using OS 3.1 I'm placing a tap-detecting image view (taken from Apple's Scroll View suite samples) in a UIScrollView and want to zoom twice on the image view when it appears. The first zoom is to make the entire image visible and the second zoom is to zoom in to a specified region. What I have right now is:
- (void)viewDidLoad {
// After adding scroll view and image view
imageScrollView.minimumZoomScale = 0.5;
imageScrollView.maximumZoomScale = 2.75;
imageScrollView.zoomScale = 1.0;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDelegate: self];
[imageScrollView zoomToRect:[imageView frame] animated:YES];
[UIView commitAnimations];
and the following to detect the end of the first zoom and to trigger the second:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
selectedRect.origin.x = 60.0;
selectedRect.origin.y = 90.0;
selectedRect.size.width = 90.0;
selectedRect.size.height = 90.0;
imageScrollView.minimumZoomScale = 1.0;
imageScrollView.maximumZoomScale = 2.75;
imageScrollView.zoomScale = 2.5;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDelegate: self];
[imageScrollView zoomToRect:selectedRect animated:YES];
[UIView commitAnimations];
What happens is that this causes an infinite loop and the scroll view "wiggles" repeatedly between two zoomed-in points. What should I be doing differently? Thank you.
Surely you just need to check the current zoomScale as the first action in scrollViewDidEndZooming. If you are already zoomed in, don't do your new zoom.
I know this code is available to UINavigationController only.
[self.navigationController setNavigationBarHidden:YES animated:YES];
An example using blocks. This will hide a toolbar at the top of an iPad screen.
[UIView animateWithDuration:.7
animations:^(void)
{
CGRect toolbarFrame = self.toolbar.frame;
toolbarFrame.origin.y = -44; // moves iPad Toolbar off screen
self.toolbar.frame = toolbarFrame;
}
completion:^(BOOL finished)
{
self.toolbar.hidden = YES;
}];
Here is the Code:
[UIView beginAnimations:#"hideView" context:nil];
[UIView setAnimationDuration:0.7];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:toolBar cache:YES];
toolbarFrame.origin.y = 380;
toolBar.frame = toolbarFrame;
[UIView commitAnimations];
you can modify the toolBar 'y' origin.