From 2243bbd644040eee7e155d4f4e87f28ed693971a Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 8 Oct 2020 11:31:40 -0400 Subject: [PATCH] Added view controller getter. --- .../MVMCoreNavigationHandler.h | 3 +++ .../MVMCoreNavigationHandler.m | 21 ++++++++++++++++ .../MVMCoreNavigationOperation.h | 4 ++++ .../MVMCoreNavigationOperation.m | 24 +++++++++++++++---- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationHandler.h b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationHandler.h index 2810b3c..dbd71fa 100644 --- a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationHandler.h +++ b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationHandler.h @@ -116,6 +116,9 @@ // Use this to pop to the root of the stack. If no navigation controller is provided, will use the main one in app delegate. - (void)popToRootAnimated:(BOOL)animated navigationController:(nullable UINavigationController *)navigationController delegate:(nullable NSObject*)delegate completionHandler:(nullable void (^)(void))completionBlock; +/// Returns the view controllers of the navigation controller. Takes into account navigation controller animation states. +- (nullable NSArray *)getViewControllersForNavigationController:(nullable UINavigationController *)navigationController; + #pragma mark - Presentation Simple // Use this to present. diff --git a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationHandler.m b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationHandler.m index 5849d9f..d156890 100644 --- a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationHandler.m +++ b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationHandler.m @@ -260,6 +260,27 @@ [self startNavigationWithNavigationObject:navigationObject delegate:delegate completionHandler:completionBlock]; } +- (nullable NSArray *)getViewControllersForNavigationController:(nullable UINavigationController *)navigationController { + // Check if we are currently animating. + NSInteger index = [self.navigationQueue.operations indexOfObjectPassingTest:^BOOL(__kindof MVMCoreNavigationOperation * _Nonnull operation, NSUInteger idx, BOOL * _Nonnull stop) { + if (operation.isExecuting) { + *stop = YES; + return YES; + } else { + return NO; + } + }]; + + if (index != NSNotFound) { + MVMCoreNavigationOperation *operation = [self.navigationQueue.operations objectAtIndex:index]; + if (operation.navigationObject.navigationController == navigationController && operation.futureViewControllers) { + // Return the future state if animating. + return operation.futureViewControllers; + } + } + return navigationController.viewControllers; +} + #pragma mark - Presentation Simple - (void)presentViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated { diff --git a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.h b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.h index 3bcd58d..349c00c 100644 --- a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.h +++ b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.h @@ -15,8 +15,12 @@ @interface MVMCoreNavigationOperation : MVMCoreOperation +@property (nonnull, strong, nonatomic) MVMCoreNavigationObject *navigationObject; @property (nullable, weak, nonatomic) NSObject *delegate; +/// Used to keep track of future view controller state because .viewControllers is not reliable during animation. +@property (nullable, strong, nonatomic) NSArray *futureViewControllers; + - (nullable instancetype)initWithNavigationObject:(nonnull MVMCoreNavigationObject *)navigationObject; @end diff --git a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.m b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.m index bdd32eb..b700005 100644 --- a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.m +++ b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.m @@ -17,7 +17,6 @@ @interface MVMCoreNavigationOperation () -@property (strong, nonatomic) MVMCoreNavigationObject *navigationObject; @property (strong, nonatomic) id animatedTransitioning; @end @@ -95,7 +94,7 @@ switch (self.navigationObject.navigationType) { case NavigationTypePush: { - [self.navigationObject.navigationController pushViewController:self.navigationObject.viewController animated:self.navigationObject.animated]; + [self pushViewController]; } break; case NavigationTypeSet: @@ -114,7 +113,7 @@ } else { // Just push - [self.navigationObject.navigationController pushViewController:self.navigationObject.viewController animated:self.navigationObject.animated]; + [self pushViewController]; } } break; @@ -129,13 +128,15 @@ } else { // Just push - [self.navigationObject.navigationController pushViewController:self.navigationObject.viewController animated:self.navigationObject.animated]; + [self pushViewController]; } } break; case NavigationTypePop: { if (self.navigationObject.navigationController.viewControllers.count > 1) { + // Although the post animation state is currently fine with pop, store anyway as a precaution + self.futureViewControllers = [self.navigationObject.navigationController.viewControllers subarrayWithRange:NSMakeRange(0, self.navigationObject.navigationController.viewControllers.count - 1)]; [self.navigationObject.navigationController popViewControllerAnimated:self.navigationObject.animated]; } else { [self markAsFinished]; @@ -179,6 +180,10 @@ } if (self.navigationObject.viewController && (self.navigationObject.viewController != self.navigationObject.navigationController.topViewController)) { + // Store post animation state. + NSInteger index = [[self.navigationObject.navigationController viewControllers] indexOfObject:self.navigationObject.viewController]; + self.futureViewControllers = [self.navigationObject.navigationController.viewControllers subarrayWithRange:NSMakeRange(0, index + 1)]; + [self.navigationObject.navigationController popToViewController:self.navigationObject.viewController animated:self.navigationObject.animated]; } else { [self markAsFinished]; @@ -188,6 +193,9 @@ case NavigationTypePopToRoot: { if (self.navigationObject.navigationController.viewControllers.count > 1) { + // Store post animation state. + self.futureViewControllers = @[self.navigationObject.navigationController.viewControllers.firstObject]; + [self.navigationObject.navigationController popToRootViewControllerAnimated:self.navigationObject.animated]; } else { [self markAsFinished]; @@ -202,8 +210,14 @@ }]]; } +- (void)pushViewController { + // Although the post animation state is currently fine with push, store anyway as a precaution + self.futureViewControllers = [self.navigationObject.navigationController.viewControllers arrayByAddingObject:self.navigationObject.viewController]; + [self.navigationObject.navigationController pushViewController:self.navigationObject.viewController animated:self.navigationObject.animated]; +} + - (void)setViewControllers:(NSArray *)viewControllers { - + self.futureViewControllers = viewControllers; if (![self.navigationObject.navigationController.viewControllers isEqualToArray:viewControllers]) { [self.navigationObject.navigationController setViewControllers:viewControllers animated:self.navigationObject.animated]; } else {