UIPickerView selectRow时触发代码:inComponent:animated:YES是否完成?

时间:2011-08-15 23:16:27

标签: iphone events animation ios4 uipickerview

我的行动方法:

- (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];
    NSString *selectedItem = [self.column1 objectAtIndex:selectedRow];
    myLabel.text = selectedItem;  // UILabel under the picker
}

然而

    myLabel.text = selectedItem;

在动画完成之前被调用,因此它不会显示新值。

我找到了线程How to get callback from UIPickerView when the selectRow animation is done?,但答案使用了beginAnimations / commitAnimation块 - 关于哪个苹果说:“在iOS 4.0及更高版本中不鼓励使用此方法。您应该使用基于块的动画方法改为指定你的动画。“

我如何使用基于块的动画来完成此任务?

2 个答案:

答案 0 :(得分:2)

看起来Apple需要更新其UIPickerView API以支持基于块的完成处理程序。在那之前,只需等待动画的估计时间。

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

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

答案 1 :(得分:0)

你有没有试过这样的事情:

[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)];
                }
];

或者您可以直接在完成块中设置标签,如果这是动画完成后您想要做的唯一事情。

修改

上面的代码与您提到的其他线程中的代码相同,但使用的是动画块。我实际上不知道方法selectRow:inComponent:animated:是否会在同一动画块线程上运行,否则它将拥有自己的线程。由于它不起作用,这意味着它在自己的线程上运行,因此我编写的代码将不起作用。

有一种方法可以解决这个问题,即通过阻止主线程完成动画所需的时间。调用selectRow:inComponent:animated:后,可以调用[NSThread sleepForTimeInterval:1.0],并且可以调整间隔,直到达到合适的值。请注意,Apple强烈建议不要阻止主线程。就个人而言,只有当我想不出另一种方法来实现我想要做的事情以及阻塞时间是否小于1时,我才会阻止它。