1
votes

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];  
}
1

1 Answers

1
votes

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.