【问题标题】:performSelector:withObject:afterDelay method not working properly?performSelector:withObject:afterDelay 方法不能正常工作?
【发布时间】:2012-11-08 21:55:40
【问题描述】:

我有一个带有小 uiimageview 圆圈的应用程序,它在两个不同的位置淡入淡出。当用户触摸屏幕时,我希望圆圈立即淡出,并且我希望它停止淡入淡出到移动位置。所以基本上触摸屏幕会杀死圆圈。

在圈子被杀死后,虽然我希望另一个圈子产生并做同样的事情(淡入和淡出到 2 个不同的位置),直到用户触摸屏幕,然后我希望那个圈子被杀死,另一个圈子产生和等等……

这是我的简化代码:

- (void)spawnCircle {
    self.circle = [[UIImageView alloc]initWithFrame:self.rectCircle];//alocate it and give it its first frame
    self.circle.image=[UIImage imageNamed:@"circle.png"];//make its image the circle image
    [self.view addSubView:self.circle];
    [self performSelector:@selector(fadeCircleOut)withObject:self afterDelay:2];//the circle will fade out after 2 seconds
    self.isFadeCircleOutNecessary=YES;
}

- (void)fadeCircleOut {

    if (self.isFadeCircleOutNecessary){//because after the circle fades in this method is scheduled to occur after 2 seconds, well, if the user has touched the screen within that time frame we obviously don't want this method to be called because we already are fading it out
        [UIView animateWithDuration:.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{//the circle will fade out for a duration of .5 seconds
            self.circle.alpha=0;
        } completion:^(BOOL finished) {
            if (finished) {
                if (self.circle.frame.origin.x==self.rectCircle.origin.x) {//if its in the first location go to the second
                    self.circle.frame=self.rectCircle2;

                }else{//if its in the second location go to the first
                    self.circle.frame=self.rectCircle;
                }
                [self fadeCircleIn];//now were going to immediately fade it in its new location
            }
        }];
    }
}

- (void)fadeCircleIn {
    [UIView animateWithDuration:.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{//fade it in with a duration of .5 seconds
        self.circle.alpha=1;
    } completion:^(BOOL finished) {
        if (finished) {
            [self performSelector:@selector(fadeCircleOut) withObject:self afterDelay:2];//after 2 seconds the object will fade out again
        }
    }];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [UIView animateWithDuration:.5 delay:0 options:UIViewAnimationCurveLinear|UIViewAnimationOptionBeginFromCurrentState animations:^(){ self.circle.alpha=0;} completion:^(BOOL completion){//begin from current state makes it stop any animations it is currently in the middle of

        [self spawnCircle];//now another circle will pop up
        self.isFadeCircleOutNecessary=NO;
    }];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self spawnCircle];
}

所以第一次生成圆圈时效果很好,但是当下一个圆圈生成时(在用户触摸屏幕并杀死第一个圆圈之后)淡出方法不会在 2 秒后发生,它在发生时会有所不同但它通常几乎立即消失。所以performSelector:withObject:afterDelay 的延迟部分似乎无法正常工作

【问题讨论】:

  • 这是在主线程上执行的吗?
  • @H2CO3 是的,还看到我做了编辑,我忘了包括我的 (isCircleFadeOutNecessary) 东西
  • 好的,新编辑后我的答案没用了。你想要做的是修复你的整个代码设计,这个问题就会消失。通过制作一个使圆圈淡入淡出的动画来做到这一点,而不是分别调用这两个方法。如果可能,请使用CoreAnimationCABasicAnimation
  • @MindiHansenMende,上面代码的一个问题是您正在再次创建 self.circle 而没有在 touches started 方法中将其从先前的超级视图中删除。当您调用 [self spawnCircle] 时;它正在创建一个新实例,因此旧实例在视图中仍然可见,该实例已泄漏,现在无法删除。 rdelmar 的以下答案应该适合您。

标签: iphone objective-c ios methods selector


【解决方案1】:

我试用了您的代码,得到了与您相同的结果。我不确定 performSelector:withObject:afterDelay: 在幕后发生了什么,但似乎一旦你开始使用它,它仍然可以执行它的功能,即使你已经创建了另一个圈子。

我稍微更改了代码,去掉了 afterDelay 调用,而是将 2 秒的延迟放在了淡出方法中。看看这是否符合您的要求:

-(void)spawnCircle{
    self.circle=[[UIImageView alloc]initWithFrame:self.rectCircle];//alocate it and give it its first frame
    self.circle.image=[UIImage imageNamed:@"circle.png"];//make its image the circle image
    [self.view addSubview:self.circle];
    [self fadeCircleOut];
}

- (void)fadeCircleOut {

    [UIView animateWithDuration:.5 delay:2 options:UIViewAnimationOptionCurveLinear animations:^{//the circle will fade out for a duration of .5 seconds
        self.circle.alpha=0;
    } completion:^(BOOL finished) {
        if (finished) {
            if (self.circle.frame.origin.x==self.rectCircle.origin.x) {//if its in the first location go to the second
                self.circle.frame=self.rectCircle2;

            }else{//if its in the second location go to the first
                self.circle.frame=self.rectCircle;
            }
            [self fadeCircleIn];//now were going to immediately fade it in its new location
        }
    }];
}

- (void)fadeCircleIn {
    [UIView animateWithDuration:.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{//fade it in with a duration of .5 seconds
        self.circle.alpha=1;
    } completion:^(BOOL finished) {
        if (finished) {
            [self fadeCircleOut];
        }
    }];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [UIView animateWithDuration:.5 delay:0 options:UIViewAnimationCurveLinear|UIViewAnimationOptionBeginFromCurrentState animations:^{
        self.circle.alpha=0;
    }
                     completion:^(BOOL completion){//begin from current state makes it stop any animations it is currently in the middle of
                         [self.circle removeFromSuperview];
                         self.circle = nil;
                         [self spawnCircle];
    }];
}

【讨论】:

    猜你喜欢
    • 2011-02-21
    • 2016-08-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多