如何在prepareForSegue被调用之前执行动画并在它完成时解除?

时间:2018-02-17 23:18:55

标签: objective-c grand-central-dispatch uistoryboardsegue nsoperationqueue nsoperation

我想实现这一目标,但我的方法不起作用:

1。用户点击“DoneButton”转到下一个视图控制器。

2。等待动画出现在prepareForSegue开始它的代码之前。

第3。一旦prepareForSegue想要加载下一个视图控制器,就停止/关闭等待的动画。

我的问题: 方法[self startWaitingAnimation];确实被调用,但我想prepareForSegue中的操作会阻塞mainThread,因此我只在prepareForSegue完成时看到动画。但是我希望首先显示动画然后在prepareForSegue中运行代码,并且在下一个View控制器准备就绪后,关闭动画。

我尝试的方法

  1. 使用信号量队列,因此在prepareForSegue内的代码完成后会关闭动画。 (没用)

  2. 使用dispatch_group。

  3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
    dispatch_group_t group = dispatch_group_create();

    - (void)goToNextVC{
           dispatch_group_async(group, queue, ^{
                 [self startWaitingAnimation];
           });
          [self performSegueWithIdentifier:@"filtersAndEdits" sender:self];
    
    }
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{          
           if ([[segue identifier] isEqualToString:@"filtersAndEdits"]) {
                dispatch_group_async(_group, _queue, ^{
    
                   AFBlurSegue *blurSegue = (AFBlurSegue *)segue;
                   blurSegue.blurRadius = 20;
                   blurSegue.tintColor = [UIColor colorWithRed:0/255 green:1/255 blue:0/255 alpha:0.1];
                   blurSegue.saturationDeltaFactor = 0.5;
    
                  //Transferring Image Data to FilterAndEdits
                  NSMutableArray*finalP =[NSMutableArray arrayWithArray:_drawableView.modifiablePointsArray];
    
                  FiltersAndEdits *FVC = [segue destinationViewController];
                  [FVC getFinalPointsArray:finalP];
                  [FVC getBgImage: self.image];
                  FVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    
               });
    
               dispatch_group_notify(_group, _queue, ^{
                  [self stopWaitingAnimation];
               });
        }else if ([[segue identifier] isEqualToString:@"HomeVC"]){
               HomeVC*homeVC = [HomeVC new];
               homeVC=segue.destinationViewController;
               [homeVC setShouldRemoveBlackScreen:YES];
               [homeVC removeBlackTempScreen];
               [self.waitingActivity stopAnimating];
        }            
    }`
    

    3.使用NSOperationQueues和NSOperation

         NSOperationQueue * queue = [[NSOperationQueue alloc] init];
         queue.maxConcurrentOperationCount =1;
    
    
    
    - (void)goToNextVC{
            self.operationA = [NSBlockOperation blockOperationWithBlock:^{
               [self startWaitingAnimation];
            }];
    
    }
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
            self.operationB = [NSBlockOperation blockOperationWithBlock:^{
    
                AFBlurSegue *blurSegue = (AFBlurSegue *)segue;
                blurSegue.blurRadius = 20;
                blurSegue.tintColor = [UIColor colorWithRed:0/255 green:1/255 blue:0/255 alpha:0.1];
                blurSegue.saturationDeltaFactor = 0.5;
    
                //Transferring Image Data to FilterAndEdits
                NSMutableArray*finalP =[NSMutableArray arrayWithArray:_drawableView.modifiablePointsArray];
    
                FiltersAndEdits *FVC = [segue destinationViewController];
                [FVC getFinalPointsArray:finalP];
                [FVC getBgImage: self.image];
                FVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
            }];
    
            self.operationC = [NSBlockOperation blockOperationWithBlock:^{
                    [self stopWaitingAnimation];
            }];
    
            [operationB addDependency:operationA]; 
            [operationC addDependency:operationB];
            [self.queue addOperation:self.operationA];
            [self.queue addOperation:operationB];
            [self.queue addOperation:operationB];
    }
    

    我该怎么办?我应该在prepareForSegue方法中使用完成处理程序吗?什么是正确的方法?感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

使用Dispatch库的Dispatch_after函数我相信它可以解决您的问题:

- (void)goToNextVC{
 //Start the animation
 dispatch_queue_t backgroundQueue;
backgroundQueue = dispatch_queue_create("backgroundQueue", 0);

dispatch_async(backgroundQueue, ^{
    [self startWaitingAnimation];
});
dispatch_async(backgroundQueue, ^{

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int)(700 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self performSegueWithIdentifier:@"filtersAndEdits" sender:self];
    });
});

}

答案 1 :(得分:0)

更新感谢@NisarAhmad,主要是有效,但并非总是如此。

有时它仍然不会让动画运行。它不保证在执行块之前始终显示动画。

- (void)goToNextVC{
     //Start the animation
     [self startWaitingAnimation];

     //Showing animation for 0.7 second.
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int)(700 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
         [self performSegueWithIdentifier:@"filtersAndEdits" sender:self];
     });
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

        if ([[segue identifier] isEqualToString:@"filtersAndEdits"]) {
            //Transferring Image Data to FilterAndEdits
            NSMutableArray*finalP =[NSMutableArray arrayWithArray:_drawableView.modifiablePointsArray];
            FiltersAndEdits *FVC = [segue destinationViewController];
            [FVC getFinalPointsArray:finalP];
            [FVC getBgImage: self.image];
            FVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
            AFBlurSegue *blurSegue = (AFBlurSegue *)segue;
            blurSegue.blurRadius = 20;
            blurSegue.tintColor = [UIColor colorWithRed:0/255 green:1/255 blue:0/255 alpha:0.1];
            blurSegue.saturationDeltaFactor = 0.5;

            //Stop the animation.
            [self stopWaitingAnimation];

        }else if ([[segue identifier] isEqualToString:@"HomeVC"]){
            //Other codes related to previous VC
        }
}