diff --git a/MVMCoreUI/BaseControllers/MFViewController.h b/MVMCoreUI/BaseControllers/MFViewController.h index 55cd6b44..de661356 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.h +++ b/MVMCoreUI/BaseControllers/MFViewController.h @@ -21,6 +21,7 @@ @import MVMCore.MVMCoreAlertObject; @import MVMCore.MVMCoreViewControllerProtocol; @import MVMCore.MVMCoreViewManagerViewControllerProtocol; +@import MVMCore.MVMCoreViewManagerProtocol; #import #import @@ -28,7 +29,6 @@ #import @class MainMenuViewController; -@class MVMCoreUITabBarPageControlViewController; @class MVMAnimationManager; @interface MFViewController : UIViewController @@ -43,9 +43,6 @@ // ** When set, they will update the support and master buttons @property (nonatomic) BOOL masterShouldBeAccessible; @property (nonatomic) BOOL supportShouldBeAccessible; -@property (nonatomic) BOOL cartShouldBeAccessible; -@property (nonatomic) BOOL communityShouldBeAccessible; -@property (nonatomic) BOOL closeButtonAccessible; // A flag for if we need to update the UI or not next time viewDidLayoutSubviews is called. @property (nonatomic) BOOL needToUpdateUI; @@ -60,8 +57,8 @@ // The page type for this screen. @property (nullable, strong, nonatomic) NSString *pageType; -// Set if this page is containted in a tab bar page control. -@property (nullable, weak, nonatomic) MVMCoreUITabBarPageControlViewController *tabBarPageControl; +// Set if this page is containted in a manager. +@property UIViewController *manager; /* The bottom progress view that is shown in the shop flow */ @property (nullable, nonatomic, strong) UIProgressView *progressView; @@ -114,9 +111,6 @@ // Handles the error. Logs and shows to screen. - (void)handleErrorAsPopup:(nonnull MVMCoreErrorObject *)error; -// Can override the standard tab page control to not cache in tab. You should be following proper caching techniques (caching, updating when needed, deleting when needed), so this should be a last resort. -- (BOOL)shouldCacheInTabPageControl; - #pragma mark - Response Handling // Called to begin observing for json updates. Called by default in view did load if pageTypesToListenFor returns an array with page types. diff --git a/MVMCoreUI/BaseControllers/MFViewController.m b/MVMCoreUI/BaseControllers/MFViewController.m index df068925..10fa557e 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.m +++ b/MVMCoreUI/BaseControllers/MFViewController.m @@ -146,7 +146,7 @@ // Sends keep alive to the server. [[MVMCoreSessionTimeHandler sharedSessionHandler] sendKeepAliveToServer:NO]; - [[MVMCoreNavigationHandler sharedNavigationHandler] popViewController:(self.tabBarPageControl ?: self) animated:YES]; + [[MVMCoreNavigationHandler sharedNavigationHandler] popViewController:(self.manager ?: self) animated:YES]; } - (void)handleErrorAsPopup:(nonnull MVMCoreErrorObject *)error { @@ -291,7 +291,7 @@ // Update separator. UIView *separatorView = (UIView *)[MVMCoreUISession sharedGlobal].splitViewController.navigationBarSeparator; separatorView.hidden = ([self isKindOfClass:[MVMCoreUITabBarPageControlViewController class]] - || self.tabBarPageControl + || self.manager || self.loadObject.requestParameters.tabWasPressed); } } @@ -307,8 +307,8 @@ - (void)setMasterShouldBeAccessible:(BOOL)masterShouldBeAccessible { MVMCoreUISplitViewController *splitViewController = [MVMCoreUISession sharedGlobal].splitViewController; - if (self.tabBarPageControl) { - [self.tabBarPageControl setMasterShouldBeAccessible:masterShouldBeAccessible]; + if (self.manager && [self.manager respondsToSelector:@selector(setMasterShouldBeAccessible:)]) { + [(MFViewController *)self.manager setMasterShouldBeAccessible:masterShouldBeAccessible]; } else if ([self isVisibleViewController]) { [splitViewController setLeftPanelIsAccessible:masterShouldBeAccessible forViewController:self]; } @@ -326,8 +326,8 @@ - (void)setSupportShouldBeAccessible:(BOOL)supportShouldBeAccessible { MVMCoreUISplitViewController *splitViewController = [MVMCoreUISession sharedGlobal].splitViewController; - if (self.tabBarPageControl) { - [self.tabBarPageControl setSupportShouldBeAccessible:supportShouldBeAccessible]; + if (self.manager && [self.manager respondsToSelector:@selector(setSupportShouldBeAccessible:)]) { + [(MFViewController *)self.manager setSupportShouldBeAccessible:supportShouldBeAccessible]; } else if ([self isVisibleViewController]) { [splitViewController setRightPanelIsAccessible:supportShouldBeAccessible forViewController:self]; } @@ -430,7 +430,7 @@ [super viewWillAppear:animated]; // Update the navigation bar ui when view is appearing. Don't handle if there is a tab bar page control, it will be handled later. - if (!self.tabBarPageControl) { + if (!self.manager) { [self updateNavigationBarUI:self.navigationController]; } } @@ -439,7 +439,7 @@ [super viewDidAppear:animated]; // Don't track page state if there is a tab bar page control, it will be handled later. - if (!self.tabBarPageControl) { + if (!self.manager) { [self adobeTrackPageState]; } @@ -584,8 +584,8 @@ [[MVMCoreUISession sharedGlobal].splitViewController.rightPanel willOpenWithActionInformation:actionInformation]; } - if (self.tabBarPageControl) { - [self.tabBarPageControl handleBackAction:actionInformation additionalData:additionalData]; + if ([self.manager respondsToSelector:@selector(handleBackAction:additionalData:)]) { + [((UIViewController *)self.manager) handleBackAction:actionInformation additionalData:additionalData]; } else { [self dismiss]; } @@ -717,12 +717,10 @@ - (void)viewControllerReadyInManager:(nonnull id )manager { // The screen is officially ready. Only update the navigation bar if initial load has finished. - if (manager == self.tabBarPageControl) { - if (self.initialLoadFinished) { - [self updateNavigationBarUI:self.tabBarPageControl.navigationController]; - } - [self adobeTrackPageState]; + if (self.initialLoadFinished) { + [self updateNavigationBarUI:self.manager.navigationController]; } + [self adobeTrackPageState]; } #pragma mark - adobe analytics diff --git a/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.h b/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.h index 6ee1e9e6..7bfaced4 100644 --- a/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.h +++ b/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.h @@ -14,20 +14,21 @@ @interface MVMCoreUITabBarPageControlViewController : MFViewController @property (nullable, weak, nonatomic) TopTabbar *tabBar; -@property (nonnull, strong, nonatomic, readonly) MFViewController *viewController; +@property (nonnull, strong, nonatomic, readonly) UIViewController *viewController; @property (assign, nonatomic, readonly) BOOL tabbarIsShown; // Can be used to store values for pages on different tabs to share. @property (nullable, strong, nonatomic) NSMutableDictionary *sharedObjects; // For server driven architecture. -- (nullable instancetype)initWithViewController:(nonnull MFViewController *)viewController loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo; -- (nullable instancetype)initWithViewController:(nonnull MFViewController *)viewController loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo shoudEnableSwipeGestures:(BOOL)enableSwipeGestures; +- (nullable instancetype)initWithViewController:(nonnull UIViewController *)viewController loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo; +- (nullable instancetype)initWithViewController:(nonnull UIViewController *)viewController loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo shoudEnableSwipeGestures:(BOOL)enableSwipeGestures; // For client driven architecture -- (nullable instancetype)initWithViewControllers:(nonnull NSArray *)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo; -- (nullable instancetype)initWithViewControllers:(nonnull NSArray *)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo shoudEnableSwipeGestures:(BOOL)enableSwipeGestures; -- (nullable instancetype)initWithViewControllers:(nonnull NSArray *)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo selectedIndex:(NSUInteger)selectedIndex shoudEnableSwipeGestures:(BOOL)enableSwipeGestures; +- (nullable instancetype)initWithViewControllers:(nonnull NSArray *>*)viewControllers tabNames:(nonnull NSArray *)tabNames loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo; +- (nullable instancetype)initWithViewControllers:(nonnull NSArray *>*)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo; +- (nullable instancetype)initWithViewControllers:(nonnull NSArray *>*)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo shoudEnableSwipeGestures:(BOOL)enableSwipeGestures; +- (nullable instancetype)initWithViewControllers:(nonnull NSArray *>*)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo selectedIndex:(NSUInteger)selectedIndex shoudEnableSwipeGestures:(BOOL)enableSwipeGestures; // Returns the number of tabs - (NSInteger)numberOfTabs; diff --git a/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.m b/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.m index 5c654a2f..96d269c3 100644 --- a/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.m +++ b/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.m @@ -26,7 +26,7 @@ @property (nullable, weak, nonatomic) UINavigationController *tabNavigationController; @property (nullable, strong, nonatomic) NSArray *tabsInfo; -@property (nonnull, strong, nonatomic, readwrite) MFViewController *viewController; +@property (nonnull, strong, nonatomic, readwrite) UIViewController *viewController; @property (nonnull, strong, nonatomic) NSMutableArray *viewControllers; @property (nonnull, strong, nonatomic) SeparatorView *tabbarSeparator; @property (assign, nonatomic, readwrite) BOOL tabbarIsShown; @@ -51,28 +51,43 @@ @implementation MVMCoreUITabBarPageControlViewController -- (nullable instancetype)initWithViewController:(nonnull MFViewController *)viewController loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo { +- (nullable instancetype)initWithViewController:(nonnull UIViewController *)viewController loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo { if (self = [super init]) { self.viewController = viewController; self.loadObject = loadObject; self.tabsInfo = tabsInfo; self.pageType = viewController.pageType; - - if ([viewController isKindOfClass:[MFViewController class]]) { - ((MFViewController *)viewController).tabBarPageControl = self; + if ([viewController respondsToSelector:@selector(setManager:)]) { + ((UIViewController *)viewController).manager = self; } } return self; } -- (nullable instancetype)initWithViewController:(nonnull MFViewController *)viewController loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo shoudEnableSwipeGestures:(BOOL)enableSwipeGestures { +- (nullable instancetype)initWithViewController:(nonnull UIViewController *)viewController loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo shoudEnableSwipeGestures:(BOOL)enableSwipeGestures { if (self = [self initWithViewController:viewController loadObject:loadObject tabsInfo:tabsInfo]) { self.shouldEnableSwipeGestures = enableSwipeGestures; } return self; } -- (nullable instancetype)initWithViewControllers:(nonnull NSArray *)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo { +- (nullable instancetype)initWithViewControllers:(nonnull NSArray *>*)viewControllers tabNames:(nonnull NSArray *)tabNames loadObject:(nullable MVMCoreLoadObject *)loadObject tabsInfo:(nonnull NSArray *)tabsInfo { + UIViewController *viewController = [viewControllers firstObject]; + if (self = [self initWithViewController:viewController loadObject:loadObject tabsInfo:tabsInfo]) { + self.viewControllers = [viewControllers mutableCopy]; + self.tabNames = tabNames; + self.clientDriven = YES; + self.selectedIndex = 0; + for (UIViewController *viewController in self.viewControllers) { + if ([viewController respondsToSelector:@selector(setManager:)]) { + ((UIViewController *)viewController).manager = self; + } + } + } + return self; +} + +- (nullable instancetype)initWithViewControllers:(nonnull NSArray *>*)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo { MFViewController *viewController = [viewControllers firstObject]; if (self = [self initWithViewController:viewController loadObject:viewController.loadObject tabsInfo:tabsInfo]) { self.viewControllers = [viewControllers mutableCopy]; @@ -80,13 +95,13 @@ self.clientDriven = YES; self.selectedIndex = 0; for (MFViewController *viewController in self.viewControllers) { - viewController.tabBarPageControl = self; + viewController.manager = self; } } return self; } -- (nullable instancetype)initWithViewControllers:(nonnull NSArray *)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo selectedIndex:(NSUInteger)selectedIndex shoudEnableSwipeGestures:(BOOL)enableSwipeGestures { +- (nullable instancetype)initWithViewControllers:(nonnull NSArray *>*)viewControllers tabNames:(nonnull NSArray *)tabNames tabsInfo:(nonnull NSArray *)tabsInfo selectedIndex:(NSUInteger)selectedIndex shoudEnableSwipeGestures:(BOOL)enableSwipeGestures { MFViewController *viewController = [viewControllers objectAtIndex:selectedIndex ofType:[MFViewController class]]; if (self = [self initWithViewController:viewController loadObject:viewController.loadObject tabsInfo:tabsInfo shoudEnableSwipeGestures:enableSwipeGestures]) { self.viewControllers = [viewControllers mutableCopy]; @@ -94,7 +109,7 @@ self.clientDriven = YES; self.selectedIndex = selectedIndex; for (MFViewController *viewController in self.viewControllers) { - viewController.tabBarPageControl = self; + viewController.manager = self; } } return self; @@ -107,6 +122,60 @@ return self; } +#pragma mark - Pass Through + +- (BOOL)isMasterInitiallyAccessible { + return [self.viewController isKindOfClass:MFViewController.class] && [(MFViewController *)self.viewController isMasterInitiallyAccessible]; +} + +- (BOOL)isSupportInitiallyAccessible { + return [self.viewController isKindOfClass:MFViewController.class] && [(MFViewController *)self.viewController isSupportInitiallyAccessible]; +} + +- (void)backButtonPressed { + if ([self.viewController respondsToSelector:@selector(backButtonPressed)]) { + [self.viewController performSelector:@selector(backButtonPressed)]; + } else { + [[MVMCoreSessionTimeHandler sharedSessionHandler] sendKeepAliveToServer:NO]; + [[MVMCoreNavigationHandler sharedNavigationHandler] popViewController:self.viewController animated:YES]; + } +} + +- (BOOL)navigationBarHidden { + return [self.viewController isKindOfClass:MFViewController.class] && [(MFViewController *)self.viewController navigationBarHidden]; +} + +- (BOOL)navigationBarTransparent { + return [self.viewController isKindOfClass:MFViewController.class] && [(MFViewController *)self.viewController navigationBarTransparent]; +} + +- (UIColor *)navigationBarColor { + if ([self.viewController isKindOfClass:MFViewController.class]) { + return [(MFViewController *)self.viewController navigationBarColor]; + } else { + return [super navigationBarColor]; + } +} + +- (UIColor *)navigationBarTintColor { + if ([self.viewController isKindOfClass:MFViewController.class]) { + return [(MFViewController *)self.viewController navigationBarTintColor]; + } else { + return [super navigationBarTintColor]; + } +} + +// Sets the screen to use the screen heading of the lower screen. +- (NSString *)screenHeading { + if ([self.viewController isKindOfClass:MFViewController.class]) { + return [(MFViewController *)self.viewController screenHeading]; + } else { + return [super screenHeading]; + } +} + +#pragma mark - View Cycle + - (void)loadView { self.tabbarIsShown = YES; UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; @@ -177,7 +246,7 @@ self.selectedIndex = i; [tabbar selectIndex:self.selectedIndex animated:NO]; - if ([self.viewController shouldCacheInTabPageControl]) { + if ([self.viewController respondsToSelector:@selector(shouldCacheInTabPageControl)] && [((UIViewController *)self.viewController) shouldCacheInTabPageControl]) { [viewControllers addObject:self.viewController]; } else { [viewControllers addObject:[NSNull null]]; @@ -210,34 +279,6 @@ self.view = view; } -- (BOOL)isMasterInitiallyAccessible { - return [self.viewController isMasterInitiallyAccessible]; -} - -- (BOOL)isSupportInitiallyAccessible { - return [self.viewController isSupportInitiallyAccessible]; -} - -- (void)backButtonPressed { - [self.viewController backButtonPressed]; -} - -- (BOOL)navigationBarHidden { - return [self.viewController navigationBarHidden]; -} - -- (BOOL)navigationBarTransparent { - return [self.viewController navigationBarTransparent]; -} - -- (UIColor *)navigationBarColor { - return [self.viewController navigationBarColor]; -} - -- (UIColor *)navigationBarTintColor { - return [self.viewController navigationBarTintColor]; -} - - (void)viewDidLoad { [super viewDidLoad]; self.shouldTriggerStartAnimations = NO; @@ -252,7 +293,7 @@ // Notify the view controller it is showing. if ([self.viewController respondsToSelector:@selector(viewControllerReadyInManager:)]) { - [self.viewController viewControllerReadyInManager:self]; + [((UIViewController *)self.viewController) viewControllerReadyInManager:self]; } } @@ -278,7 +319,7 @@ // Notify showing view we will disappear. if ([self.viewController respondsToSelector:@selector(managerWillDisappear:)]) { - [self.viewController managerWillDisappear:self]; + [((UIViewController *)self.viewController) managerWillDisappear:self]; } } @@ -301,11 +342,6 @@ } } -// Sets the screen to use the screen heading of the lower screen. -- (NSString *)screenHeading { - return [self.viewController screenHeading]; -} - #pragma mark- Extra Custom Tab getters - (NSInteger)numberOfTabs { @@ -413,19 +449,23 @@ requestParameters.loadStyle = MFLoadStyleReplaceCurrent; requestParameters.tabWasPressed = YES; [super handleOpenPageForRequestParameters:[self getRequestParametersForNewTabLoad:requestParameters actionInformation:actionInformation additionalData:additionalData] actionInformation:actionInformation additionalData:additionalData]; + } else if ([self.viewController respondsToSelector:@selector(handleOpenPageForRequestParameters:actionInformation:additionalData:)]) { + [((UIViewController *)self.viewController) handleOpenPageForRequestParameters:requestParameters actionInformation:actionInformation additionalData:additionalData]; } else { - [self.viewController handleOpenPageForRequestParameters:requestParameters actionInformation:actionInformation additionalData:additionalData]; + [super handleOpenPageForRequestParameters:requestParameters actionInformation:actionInformation additionalData:additionalData]; } } - (void)topTabbar:(nonnull TopTabbar *)topTabbar didSelectItemAtIndex:(NSInteger)index { } -- (nullable id )navigationController:(nonnull UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(nonnull MFViewController *)fromVC toViewController:(nonnull MFViewController *)toVC { +- (nullable id )navigationController:(nonnull UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(nonnull UIViewController *)fromVC toViewController:(nonnull UIViewController *)toVC { // Tab bars animate left and right navigation accordingly. if (navigationController == self.tabNavigationController) { - toVC.tabBarPageControl = self; + if ([toVC respondsToSelector:@selector(setManager:)]) { + ((UIViewController *)toVC).manager = self; + } if (self.selectedIndex == self.previousIndex) { return nil; } else if (self.previousIndex < self.selectedIndex) { @@ -454,23 +494,23 @@ } } -- (void)changedToNewController:(MFViewController *)viewController { +- (void)changedToNewController:(UIViewController *)viewController { self.viewController = viewController; self.pageType = viewController.pageType; self.navigationItem.title = viewController.navigationItem.title; self.navigationItem.titleView = viewController.navigationItem.titleView; if ([self.viewController respondsToSelector:@selector(viewControllerReadyInManager:)]) { - [viewController viewControllerReadyInManager:self]; + [((UIViewController *)self.viewController) viewControllerReadyInManager:self]; } } -- (void)navigationController:(UINavigationController *)navigationController willDisplayViewController:(MFViewController *)viewController { +- (void)navigationController:(UINavigationController *)navigationController willDisplayViewController:(UIViewController *)viewController { if (navigationController == self.tabNavigationController) { - if ([viewController shouldCacheInTabPageControl]) { + if ([viewController respondsToSelector:@selector(shouldCacheInTabPageControl)] && [((UIViewController *)viewController) shouldCacheInTabPageControl]) { [self.viewControllers replaceObjectAtIndex:self.selectedIndex withObject:viewController]; } - if ([viewController isKindOfClass:[MFViewController class]]) { - ((MFViewController *)viewController).tabBarPageControl = self; + if ([viewController respondsToSelector:@selector(setManager:)]) { + ((UIViewController *)viewController).manager = self; } // Wait to shift tab bar until after transition if we are custom animating swipe, otherwise shift now. @@ -481,7 +521,7 @@ } } -- (void)navigationController:(UINavigationController *)navigationController displayedViewController:(MFViewController *)viewController { +- (void)navigationController:(UINavigationController *)navigationController displayedViewController:(UIViewController *)viewController { if (navigationController == self.tabNavigationController) { // Track select if we need to if (self.needToTrackTabSelect) {