iteration one

This commit is contained in:
Pfeil, Scott Robert 2020-06-02 13:35:07 -04:00
parent 544d5767e0
commit 90d2df6fb0
4 changed files with 101 additions and 9 deletions

View File

@ -9,9 +9,12 @@
#import "MVMCoreOperation.h"
#import <UIKit/UIKit.h>
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
@interface MVMCoreDismissViewControllerOperation : MVMCoreOperation
@property (nullable, weak, nonatomic) NSObject<MVMCorePresentationDelegateProtocol> *delegate;
// Goes up the presentation chain to only dismiss the top presented.
- (nullable instancetype)initAndDismissTopViewController:(nullable UIViewController *)viewController animated:(BOOL)animated;

View File

@ -14,7 +14,7 @@
@class MVMCoreNavigationObject;
@class MVMCoreLoadObject;
@interface MVMCoreNavigationHandler : NSObject
@interface MVMCoreNavigationHandler : NSObject <UINavigationControllerDelegate>
// Returns the shared instance of this singleton
+ (nullable instancetype)sharedNavigationHandler;
@ -25,6 +25,8 @@
// reference to main navigation controller
@property (nullable, weak, nonatomic) UINavigationController *navigationController;
/// A list of possible delegates looking for information.
@property (nonnull, strong, nonatomic) NSPointerArray <MVMCorePresentationDelegateProtocol>*delegates;
// Will navigate appropriately based on the load style
- (void)navigateWithLoadObject:(nullable MVMCoreLoadObject *)loadObject viewController:(nonnull UIViewController *)viewController delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;
@ -35,6 +37,14 @@
// pops or dimisses as needed
- (void)removeCurrentViewController;
#pragma mark - Delegate Handling
/// Adds a listener for navigation delegate functions
- (void)addDelegate:(nonnull id <MVMCorePresentationDelegateProtocol>)delegate;
/// Removes a listener for navigation delegate functions
- (void)removeDelegate:(nullable id <MVMCorePresentationDelegateProtocol>)delegate;
#pragma mark - Navigation Simple
// Uses the default navigation controller in app delegate

View File

@ -19,7 +19,7 @@
#import "MVMCoreLoadingOverlayHandler.h"
#import "MVMCoreDispatchUtility.h"
@interface MVMCoreNavigationHandler ()
@interface MVMCoreNavigationHandler() <MVMCorePresentationDelegateProtocol>
@property (strong, nonatomic) NSOperationQueue *navigationQueue;
@property (strong, nonatomic) NSOperationQueue *presentationQueue;
@ -47,10 +47,14 @@
self.presentationQueue = [[NSOperationQueue alloc] init];
self.presentationQueue.maxConcurrentOperationCount = 1;
self.delegates = (NSPointerArray <MVMCorePresentationDelegateProtocol>*)[NSPointerArray weakObjectsPointerArray];
}
return self;
}
#pragma mark - Navigation Helpers
- (void)navigateWithLoadObject:(nullable MVMCoreLoadObject *)loadObject viewController:(nonnull UIViewController *)viewController delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock {
BOOL shouldAnimate = !loadObject.requestParameters.shouldNotAnimatePush;
@ -97,8 +101,8 @@
navigationObject.stopLoadingOverlay = YES;
MVMCoreNavigationOperation *navigationOperation = [[MVMCoreNavigationOperation alloc] initWithNavigationObject:navigationObject];
navigationOperation.delegate = delegate;
navigationOperation.completionBlock = completionBlock;
navigationOperation.delegate = self;
navigationOperation.completionBlock = [self getCompletionAndHandleDelegate:delegate completionHandler:completionBlock];
[self.navigationQueue addOperation:navigationOperation];
}
@ -284,8 +288,8 @@
[MVMCoreLoggingHandler addErrorToLog:error];
} else {
MVMCorePresentViewControllerOperation *operation = [[MVMCorePresentViewControllerOperation alloc] initWithPresentingViewController:controllerToPresentOn presentedViewController:viewController animated:animated];
operation.delegate = delegate;
operation.completionBlock = completionBlock;
operation.delegate = self;
operation.completionBlock = [self getCompletionAndHandleDelegate:delegate completionHandler:completionBlock];
[self.presentationQueue addOperation:operation];
}
}];
@ -296,7 +300,8 @@
// Dismiss on the main navigation controller.
UIViewController *controllerToPresentOn = self.viewControllerToPresentOn ?: [UIApplication sharedApplication].keyWindow.rootViewController;
MVMCoreDismissViewControllerOperation *operation = [[MVMCoreDismissViewControllerOperation alloc] initAndDismissTopViewController:controllerToPresentOn animated:animated];
operation.completionBlock = completionBlock;
operation.delegate = self;
operation.completionBlock = [self getCompletionAndHandleDelegate:delegate completionHandler:completionBlock];
[[NSOperationQueue mainQueue] addOperation:operation];
}];
}
@ -304,7 +309,8 @@
- (void)dismissViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock {
MVMCoreDismissViewControllerOperation *operation = [[MVMCoreDismissViewControllerOperation alloc] initAndDismissViewController:viewController animated:animated];
operation.completionBlock = completionBlock;
operation.delegate = self;
operation.completionBlock = [self getCompletionAndHandleDelegate:delegate completionHandler:completionBlock];
[[NSOperationQueue mainQueue] addOperation:operation];
}
@ -313,9 +319,78 @@
// Dismiss on the main navigation controller.
UIViewController *controllerToPresentOn = self.viewControllerToPresentOn ?: [UIApplication sharedApplication].keyWindow.rootViewController;
MVMCoreDismissViewControllerOperation *operation = [[MVMCoreDismissViewControllerOperation alloc] initAndDismissViewController:controllerToPresentOn animated:animated];
operation.completionBlock = completionBlock;
operation.delegate = self;
operation.completionBlock = [self getCompletionAndHandleDelegate:delegate completionHandler:completionBlock];
[[NSOperationQueue mainQueue] addOperation:operation];
}];
}
#pragma mark - Delegate Handling
- (void)addDelegate:(nonnull id <MVMCorePresentationDelegateProtocol>)delegate {
[self.delegates addPointer:(__bridge void *)(delegate)];
}
- (void)removeDelegate:(nullable id <MVMCorePresentationDelegateProtocol>)delegate {
NSUInteger index = NSNotFound;
for (NSUInteger i = 0; i < self.delegates.count; i++) {
if (delegate == [self.delegates pointerAtIndex:i]) {
index = i;
break;
}
}
if (index != NSNotFound) {
[self.delegates removePointerAtIndex:index];
}
}
- (nullable void (^)(void))getCompletionAndHandleDelegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock {
if (!delegate) {
return completionBlock;
}
[self addDelegate:delegate];
__weak typeof(delegate) weakDelegate = delegate;
__weak typeof(self) weakSelf = self;
return ^void() {
[weakSelf removeDelegate:weakDelegate];
completionBlock();
};
}
// Below functions forward to all delegates.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
for (id <MVMCorePresentationDelegateProtocol>delegate in self.delegates) {
if (delegate && [delegate respondsToSelector:@selector(navigationController:willDisplayViewController:)]) {
[delegate navigationController:navigationController willDisplayViewController:viewController];
}
}
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
for (id <MVMCorePresentationDelegateProtocol>delegate in self.delegates) {
if (delegate && [delegate respondsToSelector:@selector(navigationController:displayedViewController:)]) {
[delegate navigationController:navigationController displayedViewController:viewController];
}
}
// Legacy Notifier: Notify that page has changed
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:MVMCoreNotificationViewControllerChanged object:nil];
});
}
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
if (delegate && [delegate respondsToSelector:@selector(navigationController:animationControllerForOperation:fromViewController:toViewController:)]) {
id animatedTransitioning = [self.delegate navigationController:navigationController animationControllerForOperation:operation fromViewController:fromVC toViewController:toVC];
if ([animatedTransitioning conformsToProtocol:@protocol(MVMCoreViewControllerAnimatedTransitioning)]) {
[animatedTransitioning addObserver:self forKeyPath:@"interactiveTransitionCanceled" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
self.animatedTransitioning = animatedTransitioning;
}
return animatedTransitioning;
} else {
return nil;
}
}
@end

View File

@ -13,6 +13,7 @@
#import "MVMCoreLoggingHandler.h"
#import "MVMCoreLoadingOverlayHandler.h"
#import "MVMCoreViewControllerAnimatedTransitioning.h"
#import "MVMCoreNavigationHandler.h"
@interface MVMCoreNavigationOperation ()
@ -225,6 +226,8 @@
[super markAsFinished];
}
#pragma mark - Delegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.navigationObject.stopLoadingOverlay) {
[[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] stopLoading:YES];
@ -234,6 +237,7 @@
if (self.delegate && [self.delegate respondsToSelector:@selector(navigationController:willDisplayViewController:)]) {
[self.delegate navigationController:navigationController willDisplayViewController:viewController];
}
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {