捕获完成动画的 UIPicker selectRow 通知

发布于 2024-09-15 11:00:59 字数 1048 浏览 7 评论 0原文

我试图捕捉特定 UIPicker 动画何时完成。

我一直在寻找这个问题的答案,但似乎常见的答案(即确保 selectRow 调用位于 beginAnimations 和 commitAnimations 调用内)不起作用。
问题在于,animationFinished 几乎在调用 commitAnimations 后立即触发,并且在实际动画停止之前很久就被触发。
认为问题可能是 selectRow 创建了自己的动画块,而我实际上并没有跟踪我想要的内容,因此我尝试使用animated:NO 调用 selectRow,希望我自己的动画块能够接管选取器的动画。这确实使animationFinished 在动画结束时触发,但动画本身变得不稳定。

如何确保我正在跟踪正确的动画或者我是否遗漏了其他内容?

任何信息将不胜感激,包括对我可能错过的适当文档的简短引用。

此致, M@

这是代码:

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

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

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

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

发布评论

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

评论(1

温馨耳语 2024-09-22 11:00:59

你走在正确的轨道上。当您在提供的代码中将自己设置为动画委托时,您就是将自己设置为您的动画块的委托。因为您没有提供动画持续时间,所以您的 didStopSelector 将立即触发。

没有“受支持”的方法可以做到这一点。几乎任何解决方案都不能保证未来兼容。

毫无疑问,苹果正在将选择器动画包装在自己的动画块中。您可以进行一些创造性的调试并确定其动画的确切持续时间,并对动画块进行硬编码以匹配。一般来说,Apple 的 UIKit 动画的持续时间是固定的,与物体移动的距离无关。 (通常约为 0.33 秒)。

我会尝试这个...
-为UIView创建一个类别方法,并重写setAnimationDuration:并在该方法内设置断点。 (最好在您准备好之前禁用它,因为它会被调用无数次。)
- 当调用 animateToRow:torRow:inComponent: 方法时,打开断点,并观察选择器视图动画块传递的值。

像我说的那样设置类别方法将有效地消除为 UIView 动画块设置持续时间的能力,我不能保证不会有任何奇怪的副作用,并且它绝对仅用于调试。

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.

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