2012-11-20 105 views
1

我有一個應用程序與一個小的uiimageview圈,淡入和淡出到兩個不同的位置。當用戶觸摸屏幕時,我希望圓圈立即淡出,並且我希望它不再進入移動位置。所以基本上觸摸屏幕殺死了圓圈。performSelector:withObject: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 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的延遲部分似乎不能正常工作

+1

這是在主線程上執行? – 2012-11-20 18:40:47

+0

@ H2CO3是的,也看到我編輯我忘了包括我的(isCircleFadeOutNecessary)的東西 –

+1

好吧,在新的編輯我的答案是沒用的。你想要做的是修復你的整個代碼設計,這個問題就會解決。通過製作讓圓圈淡入淡出而不是分別調用兩種方法的單個動畫來實現這一點。如果可能,請使用'CoreAnimation'&'CABasicAnimation'。 – Mazyod

回答

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