简体   繁体   English

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

[英]Stopping all animations being performed on different thread

I have a menu with items popping right after each other in intervals of 3 seconds, I'm doing it like so: 我有一个菜单,其中的项目在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];
    }                             
}

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. 我尝试将所有内容设置为alpha 1.0但正如预期的那样,线程继续运行并再次显示项目。

Would appreciate any ideas:) 会不会有任何想法:)
Shai. 夏嘉曦。

You could do the animations using UIView block-based animations, with the delay: set. 你可以使用UIView基于块的动画来制作动画, delay:设置。 No thread worries there. 没有线程担心。

These animations can be interrupted by starting another block-based animation with the option UIViewAnimationOptionBeginFromCurrentState set. 通过设置选项UIViewAnimationOptionBeginFromCurrentState启动另一个基于块的动画,可以中断这些动画。

For alpha transitions this is fine since it doesn't matter what the current position of the animation is. 对于alpha转换,这很好,因为动画的当前位置无关紧要。 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. 如果要移动对象,可以通过查询保存对象当前状态的view.layer.presentationLayer来获取当前位置。 You will need to import the QuartzCore framework to do this. 您需要导入QuartzCore框架才能执行此操作。 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. 这也为您提供了一个方法, removeAllAnimations ,它几乎可以听到它的声音,并且可以将任何视图直接接收到它已挂起或活动的任何动画的端点。

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. 但是您可以使用BOOL标志设置一个实例变量,指示是否已按下按钮。

For example, supposing your button's targets is the method buttonTapped . 例如,假设按钮的目标是buttonTapped方法。

Initialize you flag to NO . 将标志初始化为NO

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

    return self;
}

In your button's targets set the flag to YES . 在按钮的目标中,将标志设置为YES

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

And only modify the alpha if the flag is NO . 并且只有在标志为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;
        }
    });
}

Remember that sending messages to UIKit , should always be done on the main thread. 请记住,向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;
            });
        }
    });
}

也许你会在这个回复中找到答案,也许你会以其他方式做你的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM