停止在不同线程上执行的所有动画

发布于 12-13 17:00 字数 429 浏览 7 评论 0原文

我有一个菜单,其中的项目以 3 秒的间隔依次弹出,我这样做是这样的:

for(UIButton *menuItem in menuItems){
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (0.3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        [menuItem setAlpha:1.0];
    }                             
}

是否可以在中间停止动画(例如,当触摸按钮时)? 我尝试将所有内容设置为 alpha 1.0,但正如预期的那样,线程继续运行并再次显示项目。

希望有任何想法:)
谢伊。

I have a menu with items popping right after each other in intervals of 3 seconds, I'm doing it like so:

for(UIButton *menuItem in menuItems){
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (0.3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        [menuItem setAlpha:1.0];
    }                             
}

Is it possible to stop the animation in the middle (when a button is touched, for example) ?
I tried just setting everything to alpha 1.0 but as expected, the threads kept running and shows the items again.

Would appreciate any ideas:)
Shai.

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

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

发布评论

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

评论(3

忆离笙2024-12-20 17:00:18

您可以使用 UIView 基于块的动画来制作动画,并设置 delay: 。那里没有线程担心。

这些动画可以通过使用 UIViewAnimationOptionBeginFromCurrentState 设置选项启动另一个基于块的动画来中断。

对于 Alpha 过渡来说这很好,因为动画的当前位置是什么并不重要。如果要移动对象,可以通过查询保存对象当前状态的 view.layer.presentationLayer 来获取当前位置。您需要导入 QuartzCore 框架才能执行此操作。这还为您提供了一个方法,removeAllAnimations,它的作用与听起来差不多,并将任何视图直接带到其已挂起或活动的任何动画的端点。

You could do the animations using UIView block-based animations, with the delay: set. No thread worries there.

These animations can be interrupted by starting another block-based animation with the option UIViewAnimationOptionBeginFromCurrentStateset.

For alpha transitions this is fine since it doesn't matter what the current position of the animation is. If you are moving objects, you can get the current position by querying the view.layer.presentationLayer which holds the current state of the object. You will need to import the QuartzCore framework to do this. This also gives you a method, removeAllAnimations which will do pretty much what it sounds like and takes any view right to the endpoint of any animations it has got pending or active.

等你爱我2024-12-20 17:00:18

我不认为你可以停止已经安排好的动画。但是您可以设置一个带有 BOOL 标志的实例变量,指示按钮是否已按下。

例如,假设按钮的目标是方法 buttonTapped

将您的标志初始化为NO

- (id)init {
    if (self = [super init]) {
        buttonAlreadyTapped = NO;
    }

    return self;
}

在按钮的目标中将标志设置为YES

- (void)buttonTapped {
    self.buttonAlreadyTapped = YES;
}

如果标志为 NO,则仅修改 alpha

for (NSInteger i = 1; i <= [menuItems count]; i++) {        
    UIButton *menuItem = [menuItems objectAtIndex:i-1];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        if (!self.buttonAlreadyTapped) {
            menuItem.alpha = 1.0f;
        }
    });
}

请记住,向 UIKit 发送消息应该始终在主线程上完成。

for (NSInteger i = 1; i <= [menuItems count]; i++) {        
    UIButton *menuItem = [menuItems objectAtIndex:i-1];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        if (!self.buttonAlreadyTapped) {
            dispatch_async(dispatch_get_main_queue(), ^{
                menuItem.alpha = 1.0f;
            });
        }
    });
}

I don't think you can stop animations already scheduled. But you could set an instance variable with a BOOL flag indicating if a button was already pressed or not.

For example, supposing your button's targets is the method buttonTapped.

Initialize you flag to NO.

- (id)init {
    if (self = [super init]) {
        buttonAlreadyTapped = NO;
    }

    return self;
}

In your button's targets set the flag to YES.

- (void)buttonTapped {
    self.buttonAlreadyTapped = YES;
}

And only modify the alpha if the flag is NO.

for (NSInteger i = 1; i <= [menuItems count]; i++) {        
    UIButton *menuItem = [menuItems objectAtIndex:i-1];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        if (!self.buttonAlreadyTapped) {
            menuItem.alpha = 1.0f;
        }
    });
}

Remember that sending messages to UIKit, should always be done on the main thread.

for (NSInteger i = 1; i <= [menuItems count]; i++) {        
    UIButton *menuItem = [menuItems objectAtIndex:i-1];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        if (!self.buttonAlreadyTapped) {
            dispatch_async(dispatch_get_main_queue(), ^{
                menuItem.alpha = 1.0f;
            });
        }
    });
}
吃兔兔2024-12-20 17:00:18

也许您会在响应中找到答案也许你会用其他方式做你的事情。

Maybe you will find answer in this response and maybe you will do your stuff in other way.

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