For some reason my UIButton won't respond to UIControlEvents while animating. Here's how I animate:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[duration intValue]];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
// change parent UIView's frame
[UIView commitAnimations];
When it reaches the end, it will let me tap it... but not while it's animating. I am using UIControlEventTouchUpInside, by the way.
Thanks.
You should set the UIViewAnimationOptionAllowUserInteraction animation option
easier done with block animations:
[UIView animateWithDuration:[duration intValue] options:UIViewAnimationOptionAllowUserInteraction animations^{
//set parent UIView's frame
}];
Related
I'm working on a page-based iPhone app using Xcode 4.4 with ARC and have been stuck on this for awhile. On a certain page, a UIImageView finger needs to slide up and point to something and then slide left off the screen. This works as expected when I run it once, but when I turn the page and go back - there is now 2 fingers sliding about 0.5 seconds out of sync with eachother.
Here's the code:
-(void)fingerSwipeUp:(UIImageView *)imageView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[imageView setCenter:CGPointMake(213.75,355.5)];
[UIView commitAnimations];
}
-(void)fingerSwipeLeft:(UIImageView *)imageView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[imageView setCenter:CGPointMake(-80,355.5)];
[UIView commitAnimations];
}
UIImageView *finger = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"finger.png"]];
// position finger off the screen
[finger setFrame:CGRectMake(142.5,480,152.5,243)];
[self.view addSubview:finger];
[self performSelector:#selector(fingerSwipeUp:) withObject:finger afterDelay:6];
[self performSelector:#selector(fingerSwipeLeft:) withObject:finger afterDelay:8];
Any help greatly appreciated
I'm guessing that you're creating the "finger" view in ViewDidAppear()? If that's the case, every time the page is turned (hidden) and then gone back to, you're adding another arrow (subview). What about this instead:
if (finger == nil) {
finger = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"finger.png"]];
[finger setFrame:CGRectMake(142.5,480,152.5,243)];
[self.view addSubview:finger];
}
[self performSelector:#selector(fingerSwipeUp:) withObject:finger afterDelay:6];
[self performSelector:#selector(fingerSwipeLeft:) withObject:finger afterDelay:8];
If you've got a number of animations in a sequence, you might find it easier to use the block-based UIView animation syntax:
[UIView animateWithDuration:1.0 delay:6.0 options:UIViewAnimationCurveEaseInOut animations:^{
// animation 1
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 delay:8.0 options:UIViewAnimationCurveEaseInOut animations:^{
// animation 2
}];
}];
This will only start animation 2 after animation 1 has finished, so you don't need to worry about allowing for the duration of animation 1 when delaying animation 2.
Where is the correct place to put custom animation code for dismissing a modalviewcontroller.
I tried putting the following into viewdiddisappear, viewwilldisappear but doesn't behave correctly. Any thoughts? THanks!!
[UIView beginAnimations:#"suck" context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:103 forView:self.navigationController.view cache:YES];
[UIView setAnimationPosition:CGPointMake(260, 431)];
[UIView commitAnimations];
Try this:
UIViewController *myController = [[[MyViewController alloc] init] autorelease];
UIViewAnimationTransition transition = UIViewAnimationTransitionCurlUp; // or whatever effect you want
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:transition forView:[self window] cache:YES];
[navController presentModalViewController:myController animated:NO]; // or dismissModalViewController in your case
[UIView commitAnimations];
I think I figured it out. I followed the example in:
http://developer.apple.com/library/ios/#samplecode/BubbleLevel/Introduction/Intro.html
Basically removed the second view from superview and inserted the first view back in. The transition works correctly afterwords.
THanks for the help.
I have five images, and all i need is to animate them differently and simultaneously on the screen. I got different animation codes but they use sequence of images to create animation .. or they animate a single image. Please help
Thankyou so much #Rob and #Aadhira for your interest. Here is my code that moves one image linearly.. How can i animate it in a curve
if(isAnimate) {
NSLog(#"+30,+15");
[UIView beginAnimations: #"moveView" context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 0.5];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
searchLight1.frame = CGRectMake(searchLight1.frame.origin.x+30, searchLight1.frame.origin.y + 15, searchLight1.frame.size.width, searchLight1.frame.size.height);
[UIView commitAnimations];
isAnimate = NO;
}
else {
NSLog(#"-30,-15");
[UIView beginAnimations: #"moveView" context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 0.5];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
searchLight1.frame = CGRectMake(searchLight1.frame.origin.x-30, searchLight1.frame.origin.y -15, searchLight1.frame.size.width, searchLight1.frame.size.height);
[UIView commitAnimations];
isAnimate = YES;
}
It all depends on what kind of animation you want and what code you are having. If you post that, it would be better.
Anyhow you know how to animate a single image. Then start animating the 5 images in 5 different blocks.
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.