1

2つの異なる場所にフェードインおよびフェードアウトする小さな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正しく機能していないようです

4

1 に答える 1

1

あなたのコードを試してみたところ、あなたと同じような結果が得られました。performSelector:withObject:afterDelay: の舞台裏で何が起こっているのかはわかりませんが、1 つを開始すると、別のサークルを作成したとしても、その機能を引き続き実行できるようです。

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];
    }];
}
于 2012-11-20T20:07:41.757 に答える