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

发布于 2024-11-29 11:26:30 字数 861 浏览 1 评论 0原文

我的操作方法:

- (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动画完成?,但答案使用beginAnimations/commitAnimation block - 苹果对此表示:“在 iOS 4.0 及更高版本中不鼓励使用此方法。您应该使用基于块的动画方法来指定动画。”

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

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];
    NSString *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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最好是你 2024-12-06 11:26:30

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

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

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

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];
雪化雨蝶 2024-12-06 11:26:30

您是否尝试过这样的操作:

[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 时,我才会阻止它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文