I have used this previously in my app, and having looked over everything I cannot find the difference, but for some reason when I run:
-(void)moveSelectorToDisplayPosition:(id)sender{
int givenTag = [sender tag];
UIImageView *tempImageView = [displayedSelections objectAtIndex:givenTag];
[UIView beginAnimations:#"" context:NULL];
[UIView setAnimationDuration:.3];
tempImageView.frame = CGRectOffset(tempImageView.frame, 30 - tempImageView.frame.origin.x, 240 - tempImageView.frame.origin.y);
[UIView setAnimationDidStopSelector:#selector(loadInTextForSelectedTool:)];
[UIView commitAnimations];
}
loadInTextForSelectedTool does not get called and I cannot figure out why. No errors or anything.
This is the method I'm trying to run, could anyone let me know if they see anything amiss or maybe something I might have forgotten? I tried also setting the [UIView setAnimationDelegate:tempImageView]; but no luck :(.
-(void)loadInTextForSelectedTool:(id)sender;
Thanks.
You need to set the delegate to the controller that implements loadInTextForSelectedTool:
[UIView setAnimationDelegate:self];
Also, according to the documentation, the selector should have the following form:
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
And finally, Apple discourages the use of this animation method in iOS 4.0 or later:
Use of this method is discouraged in iOS 4.0 and later. You should use
the block-based animation methods to specify your animations instead.
Unless you need to run on 3.2 or earlier, you should be using block animations. They really simplify specifying what to do at the end of an animation.
http://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html#//apple_ref/doc/uid/TP40009503-CH6-SW1
Related
I have read apple documentation: http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html#//apple_ref/doc/uid/TP40009503-CH6-SW1
For iOS3.0 and earlier, using this:
Method1:
[UIView beginAnimations:#"ShowHideView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
...
The new one, iOS4, can do this:
Method2:
[UIView animateWithDuration:1.0 animations:^{
firstView.alpha = 0.0;
secondView.alpha = 1.0;
}];
Q1. What I want to know is, in earlier method, they have this "ShowHideView" in beginAnimations, is that method a built-in one?
Q2. Are there any others built-in methods for animation in beginAnimations? If yes, where can I find all those methods?
Q3. And lastly, can I use those methods in latter method(method2) call?
You can get all the answers to your questions in the UIView Class Reference.
Q1: ShowHideView, as you have it, is not a method at all. It is simply an "application-supplied identifier for the animations". In reality, you don't need it. When I use this method, I just use NULL instead of supplying an identifier there.
Q2: You don't set animations in the beginAnimations:context: call. You even illustrate it there by calling setAnimationCurve. You can set the animations from this typedef.
Q3: Again, you don't declare animation types in animateWithDuration:animations: call either. Utilize setAnimationCurve: to do that in that example as well.
Blocks have the benefit of being able to nest the animations (in a queue almost) using the [UIView animateWithDuration:animations:completion:] selector. You can nest another call to this method inside the finished block like so:
[UIView animateWithDuration:1.0 animations:^{
// your first animations
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
// more animations
} completion:^(BOOL finished) {
// ... maybe even more
}]
}]
I abuse this in my code and find it much easier than using the beginAnimations/commitAnimations code. And, with iOS 5 approaching, the days of needing to support iOS 3.x are slipping away.
say I have...
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
CGPoint position = myObject.center;
position.x = position.x - 10;
myObject.center = position;
[UIView commitAnimations];
Core animation happens on a separate thread is there a way to know when
an animation has finished? i.e., maybe there's some way I can hook up a
function call to know when it got finished... ?
(p.s I know I can use a timer that fires a method after say 0.5s in this
above example, but that seems pretty cheesy)
any help much appreciated!
You can set the setAnimationDidStopSelector:
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/clm/UIView/setAnimationDidStopSelector:
(void)setAnimationDidStopSelector:(SEL)selector
Then implement a method for that selector
[UIView setAnimationDidStopSelector:#selector(finishedAnimation:finished:context:)];
- (void) finishedAnimation:(NSString *)id finished:(BOOL) finished context:(void *) context {
......
}
Hope that helps.
I am displaying a ticker at the bottom of a view (think of a news channel's headlines ticker bar) in the form of a horizontal scrollview. It works correctly when I set the repeatCount to infinite but I want to be able to do some other functionality when the animation starts and stops instead. However, after reading the documentation and many examples online, I can't get setAnimationWillStartSelector/setAnimationDidStopSelector to respond.
Here's my code:
- (void)animateView {
[UIScrollView setAnimationDelegate:self];
[UIScrollView setAnimationWillStartSelector:#selector(animationStart:context:)];
[UIScrollView setAnimationDidStopSelector:#selector(animationStop:finished:context:)];
[UIScrollView beginAnimations:#"pan" context:nil];
[UIScrollView setAnimationDuration:10.0f];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIScrollView setAnimationCurve:UIViewAnimationCurveLinear];
tickerScrollView.contentOffset = CGPointMake(textLabelRect.size.width,0);
[UIScrollView commitAnimations];
}
- (void)animationStart:(NSString *)animationID context:(void *)context {
NSLog(#"animationWillStart");
}
- (void)animationStop:(NSString *)animationID finished:(BOOL)finished context:(void *)context {
NSLog(#"animationDidStop");
[self animateView];
}
At the moment this code is in my UIViewController subclass. However, I have also tried putting it all in my app delegate as well, whilst also changing the setAnimationDelegate obviously. I've tried using various animationDurations, repeatCounts, etc but still no luck.
Would really appreciate any help. Thanks
You can try putting the setAnimationDelegate, setAnimationWillStartSelector and setAnimationDidStopSelector inside the animation block. According to the iPhone OS Reference Library documentation, these methods have to be put inside the animation block in order for it to work.
Hope this helps!
aobs
I am starting an animated enlargement when an image is touched, and then scaling it back down to normal size when it is released. By using setAnimationBeginsFromCurrentState:YES the zooming effect is nice and smooth if you lift your finger part way through animating.
However, what I want to do is "lock" the larger size in place if you've touched the image for long enough for the animation to complete, but let it shrink back down as normal if you release prematurely.
Is there a way to tell whether there is currently an animation running, or whether a particular animation has completed?
I figure I can probably do this with a performSelector:afterDelay: call in touchesStarted, with a delay equal to the length of the animation and cancelling it if touchesEnded comes too soon, but I can't imagine that's the best way...?
- (void)animateStuff {
[UIView beginAnimations:#"animationName" context:nil];
[UIView setAnimationDelegate:self];
[self.view doWhatever];
[UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID
finished:(NSNumber *)finished
context:(void *)context
{
if ([finished boolValue]) {
NSLog(#"Animation Done!");
}
}
Another possibility:
[UIView animateWithDuration:0.3 animations:^{
myView.transform = CGAffineTransformMakeRotation(M_PI);
}completion:^(BOOL finished) {
NSLog(#"Animation complete!");
}];
I think "+ (void)setAnimationDidStopSelector:(SEL)selector" should do what you want. It will call the given selector on your delegate once the animation has completed.
I have an implict animation as follows:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationDelegate:self];
...
[UIView commitAnimations];
When this animation begins and ends, it triggers these delegate functions:
- (void)animationWillStart:(NSString *)animationID context:(void *)context;
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag;
I have multiple things that get animated in my viewController, and the delegate functions are getting crossed. How do I tag a particular animation so I can check which one it is in the delegate functions?
It's also odd to me that the parameter for one of these functions is a string while the other is a CAAnimation. Both of these methods get called, but am I using the wrong one or something?
For implicit animations like that, you set your animationDidStopSelector:
[UIView setAnimationDidStopSelector:#selector(animationDidEnd:finished:context:)];
and that will call your animationDidEnd as follows:
- (void) animationDidEnd:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
This is pretty much the same as the animationWillStartSelecter which calls beginAnimations:context:
For both, you can use context to pass in a tag or other values that your selectors can use to distinguish the animation.
[UIView beginAnimations:nil context:nil];
Am I crazy here or is there some reason you are passing in nil for animationID (first argument)? No need to mess with context, you can simply set the ID and then look at the ID passed into your didStop selector. That's what it's there for!