views:

102

answers:

1

Hi everyone.

I am trying to catch when a specific UIPicker animation is finished.

I have looked long for an answer to this but it seems that the common answer, which is to ensure the selectRow call is within the beginAnimations and commitAnimations calls, does not work.
The problem is that the animationFinished is triggered almost immediately after the commitAnimations is called and long before the actual animation stops.
Thinking that the problem might be that the selectRow creates its own animation block and that I'm not actually tracking what I want, I tried calling selectRow with animated:NO hoping my own animation block would then take over the animation of the picker. This did indeed make the animationFinished trigger at the end of the animation but the animation itself became jerky.

How do I make sure that I'm tracking the correct animation or am I missing something else?

Any info would be greatly appreciated including curt references to appropriate documentation I might have missed.

Best regards, M@

This is the code:

- (void) animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context {  
     NSLog(@"animation %d stopped",animationID);  
}  

- (void)animateToRow:(UIPickerView *)pickerView toRow:(NSInteger)row inComponent:(NSInteger)component
{

    [UIPickerView beginAnimations:@"1" context:nil];  
    [UIPickerView setAnimationDelegate:self];  
    [UIPickerView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];  
    [pickerView selectRow:row inComponent:component animated:YES];  
    [UIPickerView commitAnimations];  
}
A: 

You are on the right track. When you set yourself as the animation delegate in the code you have provided, you are setting yourself as the delegate for YOUR animation block. Because you haven't provided an animation duration, your didStopSelector is going to fire immediately.

There isn't a "supported" way to do this. And just about any solution has no guarantee of being future compatible.

Without a doubt, Apple is wrapping the picker animation in it's own animation blocks. You could do some creative debugging and determine the exact duration of their animation, and hard code your animation block to match. Generally, Apple's UIKit animations are of a fixed duration, regardless of the distance something has to travel. (quite often, it's about .33 seconds).

I would try this... -Create a category method for UIView, and override setAnimationDuration: and set a breakpoint inside this method. (It's probably best to disable it until you are ready for it, as it will be called an overwhelming number of times.) -When your animateToRow:torRow:inComponent: method is called, turn your breakpoint on, and watch for the value passed by the picker views animation block.

Setting a category method like I said will effectively eliminate the ability to set durations for UIView animation blocks, I can't guarantee that there won't be any odd side effects, and it is absolutely intended for debugging only.

Jerry Jones
Thank you for your quick and clear answer. Whilst I will certainly try this to satisfy my curiosity, it seems a bit too...unsupported to rely on for an actual app store product.First and foremost my question is to ensure that I'm not missing a known pattern or official API way of doing this. If no-one else comes up with one, and you are suggesting there isn't one, I will either have to find a different path or reconsider the use altogether. Best regards, M@
Teo Sartori