0
votes

I want to achieve this but non of my approaches work:

1. user taps "DoneButton" to go to the next view controller.

2. waiting animation shows up before prepareForSegue starts it's code.

3. Stop/dismiss the waiting animation once prepareForSegue wants to load the next view controller.

My problem: The method [self startWaitingAnimation]; does get called but I guess the operation inside prepareForSegue blocks the mainThread, hence I only see the animation just when prepareForSegue is finished. but I want the animation to show up first and then run the code inside the prepareForSegue and once the next View controller is ready, dismiss the animation.

Ways I tried to do it,

  1. Using semaphore queues so it would dismiss the animation after the code inside prepareForSegue finished. (didn't work)

  2. Using dispatch_group.

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.Using NSOperationQueues and 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];
}

What should I do? Should I use completion handler inside prepareForSegue method? what is the right approach? Appreciate any help.

2
Why won’t you use UIView.animateWithDuration with completion handler. Inside you put the startanimating, duration 0.4. In completion block you add the performSegue.Tom Derry Marion Mantilla
Because I'm using DGActivityIndicatorView, it's not an animation with animateWithDurationReza.Ab
Have you tried using dispatch_group_wait?Tom Derry Marion Mantilla
Have you tried dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block) . . . . . . Start animation than call the Dispatch_after function and pass the [self performSegueWithIdentifier:@"filtersAndEdits" sender:self]; in block.Nisar Ahmad

2 Answers

1
votes

Use Dispatch_after function of Dispatch library I believe it will solve your problem:

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

}
0
votes

UPDATE Thanks to @NisarAhmad it mostly works but not always.

It sometimes still doesn't let the animation to run. It doesn't guarantee to let the animation to show up always before executing the block.

- (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
        }
}