Reputation: 1215
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,
Using semaphore queues so it would dismiss the animation after the code inside prepareForSegue finished. (didn't work)
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.
Upvotes: 0
Views: 61
Reputation: 937
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];
});
});
}
Upvotes: 1
Reputation: 1215
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
}
}
Upvotes: 0