开发者

Triggering code when UIPickerView selectRow:inComponent:animated:YES is completed?

开发者 https://www.devze.com 2023-03-28 12:34 出处:网络
My action method: - (IBAction)buttonPressed { // animate picker to random row (picker is a UIPickerView)

My action method:

- (IBAction)buttonPressed {
    // animate picker to random row (picker is a UIPickerView)
    int row = random() % [self.column1 count];  
    [picker selectRow:row inComponent:0 animated:YES];  
    [picker reloadComponent:0];

    // display new selected row content
    int selectedRow = [picker selectedRowInComponent:0];
    NSStr开发者_如何学编程ing *selectedItem = [self.column1 objectAtIndex:selectedRow];
    myLabel.text = selectedItem;  // UILabel under the picker
}

However

    myLabel.text = selectedItem;

gets called before the animation has completed and so it doesn't display the new value.

I found the thread How to get callback from UIPickerView when the selectRow animation is done?, but the answer uses a beginAnimations/commitAnimation block - about which apple says: "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."

How would I use block-based animation to accomplish this?


It looks like Apple needs to update their UIPickerView API to support a block based completion handler. Until then, just wait the estimated time of the animation.

[picker selectRow:0 inComponent:0 animated:YES];  

[self performSelector:@selector(setMyLabel)  // setMyLabel - my function
           withObject:nil
           afterDelay:0.4];


Have you tried something like this:

[UIView animateWithDuration:2.0
                     delay:0.0
                   options:UIViewAnimationOptionCurveEaseInOut
                animations:^{
                   // the animation code
                   [myPickerView selectRow:0 inComponent:0 animated:YES];
                }
                completion:^(BOOL finished) {
                   [self performSelector:@selector(setMyLabel)];
                }
];

Or you could just set the label directly in the completion block, if that's the only thing you want to do after the animation completes.

EDIT:

The code above is the same as the code in the other thread you've mentioned, but using animation blocks instead. I actually didn't know if the method selectRow:inComponent:animated: will run on the same animation block thread or it will have its own thread. Since it didn't work, that means it runs on its own thread so the code I wrote won't work.

There is one way around to solve this, which is by blocking the main thread for the time needed for the animation to complete. You can call [NSThread sleepForTimeInterval:1.0] after your call to selectRow:inComponent:animated:, and you can adjust the interval until you reach a suitable value. Note that blocking the main thread is highly discouraged by Apple. Personally I would block it only if I couldn't think of another way to achieve what I'm trying to do and if the blocking time is smaller than 1.

0

精彩评论

暂无评论...
验证码 换一张
取 消