diff --git a/MVMCoreUI/Containers/NavigationController/NavigationController.swift b/MVMCoreUI/Containers/NavigationController/NavigationController.swift index c613d3a7..36be6d45 100644 --- a/MVMCoreUI/Containers/NavigationController/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController/NavigationController.swift @@ -43,11 +43,14 @@ import Combine */ @MainActor public func subscribe() { - NavigationHandler.shared().onNavigationWillBegin.sink { [weak self] navigationType in + NavigationHandler.shared().onNavigationWillBegin.sink { [weak self] operation in guard let self = self, - self == navigationType.getNavigationController(), - let viewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, + self == operation.navigationType.getNavigationController(), + let viewController = NavigationHandler.shared().getViewControllers(for: self).last, let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } + if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { + MVMCoreViewManagerViewControllerProtocolHelper.helpSetManager(self, viewController: controller) + } if let model = getNavigationModel(from: newViewController) { self.setNavigationItem(with: model, for: viewController) self.setNavigationBarUI(with: model) @@ -55,10 +58,10 @@ import Combine self.manager?.willDisplay?(newViewController) }.store(in: &cancellables) - NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] navigationType in + NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] operation in guard let self = self, - self == navigationType.getNavigationController(), - let viewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, + self == operation.navigationType.getNavigationController(), + let viewController = NavigationHandler.shared().getViewControllers(for: self).last, let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } self.manager?.displayedViewController?(newViewController) if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { @@ -74,8 +77,7 @@ import Combine /// Verifies the controller is the currently displayed controller. public func isDisplayed(viewController: UIViewController) -> Bool { - guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, - viewController == MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) else { + guard viewController == getViewController() else { return false } return true @@ -120,7 +122,7 @@ extension NavigationController: MVMCoreViewManagerProtocol { /// Updates the navigation item/bar of the current view controller based on the passed in model and view controller. @MainActor private func updateNavigationView(with model: NavigationItemModelProtocol, for viewController: UIViewController) { - guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last else { return } + guard let topViewController = NavigationHandler.shared().getViewControllers(for: self).last else { return } setNavigationItem(with: model, for: topViewController, coordinatingWith: viewController as? PageBehaviorHandlerProtocol) setNavigationBarUI(with: model) diff --git a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift index 5ffe202c..625f0a25 100644 --- a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift +++ b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift @@ -39,7 +39,7 @@ public extension UINavigationController { if model.hidesSystemBackButton, model.alwaysShowBackButton != false { if let backButtonModel = model.backButton, - MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).count ?? 0 > 1 || model.alwaysShowBackButton ?? false { + NavigationHandler.shared().getViewControllers(for: self).count > 1 || model.alwaysShowBackButton ?? false { leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } if let leftItemModels = model.additionalLeftButtons { @@ -114,4 +114,11 @@ public extension UINavigationController { setNavigationBarHidden(model.hidden, animated: true) } + + @MainActor + func getViewController() -> UIViewController? { + guard let topViewController = getViewControllers().last, + let viewController = MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) else { return nil } + return viewController + } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index dadd5025..20f4449c 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -54,7 +54,7 @@ public extension MVMCoreUISplitViewController { let mvmViewController = viewController as? MVMCoreViewControllerProtocol tabBar?.delegateObject = mvmViewController?.delegateObject?() as? MVMCoreUIDelegateObject - let navigationIndex = (navigationController != nil ? (MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController!).count ?? 1) : 1) - 1 + let navigationIndex = (navigationController != nil ? NavigationHandler.shared().getViewControllers(for: navigationController!).count : 1) - 1 // Set the highlighted index. In terms of priority, Page > Action > Previous. if let index = ((viewController as? PageProtocol)?.pageModel as? TabPageModelProtocol)?.tabBarIndex { @@ -112,8 +112,8 @@ public extension MVMCoreUISplitViewController { */ @MainActor func setLeftNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { - guard let viewControllers = MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController), - let topViewController = viewControllers.last else { return } + let viewControllers = NavigationHandler.shared().getViewControllers(for: navigationController) + guard let topViewController = viewControllers.last else { return } var leftItems: [UIBarButtonItem] = [] let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject @@ -163,7 +163,7 @@ public extension MVMCoreUISplitViewController { */ @MainActor func setRightNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { - guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController).last else { return } + guard let topViewController = NavigationHandler.shared().getViewControllers(for: navigationController).last else { return } let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject var rightItems: [UIBarButtonItem] = [] @@ -268,6 +268,17 @@ extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol { } @objc public extension MVMCoreUISplitViewController { + @objc func goBack() { + Task(priority: .userInitiated) { @MainActor in + if let viewController = getCurrentDetailViewController() as? MVMCoreUIDetailViewProtocol, + let backButtonPressed = viewController.backButtonPressed { + backButtonPressed() + } else { + await NavigationHandler.shared().popTopViewController() + } + } + } + /// Subscribes for notification events. @objc func subscribeForNotifications() { guard cancellables == nil else { return } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index c499596a..c43d17d9 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -191,14 +191,7 @@ CGFloat const PanelAnimationDuration = 0.2; } - (IBAction)backButtonPressed:(id)sender { - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - UIViewController *detailViewController = [self getCurrentDetailViewController]; - if ([detailViewController conformsToProtocol:@protocol(MVMCoreUIDetailViewProtocol)] && [detailViewController respondsToSelector:@selector(backButtonPressed)]) { - [((UIViewController *)detailViewController) backButtonPressed]; - } else { - [[MVMCoreNavigationHandler sharedNavigationHandler] popTopViewControllerAnimated:YES]; - } - }]; + [self goBack]; } - (IBAction)rightPanelButtonPressed:(id)sender { @@ -257,7 +250,7 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended { NSMutableArray *leftBarButtonItems = [NSMutableArray array]; - if (self.navigationController && [MVMCoreNavigationHandler.sharedNavigationHandler getViewControllersForNavigationController:self.navigationController].count > 1) { + if (self.navigationController && [self.navigationController getViewControllers].count > 1) { [leftBarButtonItems addObject:self.backButton]; } if ((accessible && !extended) && self.leftPanelButton) { @@ -1098,17 +1091,7 @@ CGFloat const PanelAnimationDuration = 0.2; } - (UIViewController *)getCurrentVisibleController { - UIViewController *baseViewController = [MVMCoreNavigationHandler sharedNavigationHandler].viewControllerToPresentOn ?: [MVMCoreGetterUtility getKeyWindow].rootViewController; - UIViewController *viewController = nil; - while (baseViewController.presentedViewController && !baseViewController.presentedViewController.isBeingDismissed) { - viewController = baseViewController.presentedViewController; - baseViewController = viewController; - } - // if it is not presented viewcontroller, existing BAU logic will be working - if (!viewController) { - viewController = [MVMCoreUIUtility getViewControllerTraversingManagers:self.navigationController.topViewController]; - } - return viewController; + return [MVMCoreUIUtility getCurrentVisibleController]; } - (UIViewController *)getCurrentDetailViewController { diff --git a/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift b/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift index 233a1f57..eb4dcdda 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift @@ -90,6 +90,8 @@ fileprivate enum SubNavPanningDirection : Int { switch (pan.state) { case .began: + print("sssss \(#function) began") + // Begin the transition to the next page. panning = true if velocityX < 0 && pannableFrameRight.contains(locationInView) { @@ -117,11 +119,15 @@ fileprivate enum SubNavPanningDirection : Int { shouldCompleteTransition = percentage > 0.65; update(percentage) delegate?.update(percentage: percentage) - + print("sssss \(#function) changed \(percentage)") + case .cancelled: cancel() - + print("sssss \(#function) cancelled") + case .ended: + print("sssss \(#function) ended") + if ((percentage < 0) != (velocityX < 0)) && abs(velocityX) > 50 { // If we are moving back toward the previous view we want to cancel. (the speed threshold is for shaky hands) cancel() diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index c2c01c1b..7bdee349 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -229,7 +229,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, hideNavigationBarLine(true) } - public func navigationController(_ navigationController: UINavigationController, willDisplay viewController: UIViewController) { + public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { guard navigationController == subNavigationController else { return } if let viewController = viewController as? UIViewController & MVMCoreViewManagerViewControllerProtocol & MVMCoreViewControllerProtocol { @@ -247,7 +247,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, commitTo(controller: viewController) } - public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) { + public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { guard navigationController == subNavigationController else { return } // Need to track swipe action. if needToTrackTabSelect { diff --git a/MVMCoreUI/Notification/NotificationHandler.swift b/MVMCoreUI/Notification/NotificationHandler.swift index c031ac77..627d611a 100644 --- a/MVMCoreUI/Notification/NotificationHandler.swift +++ b/MVMCoreUI/Notification/NotificationHandler.swift @@ -356,11 +356,11 @@ open class NotificationHandler { /// Registers to know when pages change. private func registerForPageChanges() { - cancellable = NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] navigationType in + cancellable = NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] operation in // Update displayable for each top alert operation when page type changes, in top queue priority order. guard let self = self, self.queue.operations.count > 0, - let navigationController = navigationType.getNavigationController(), + let navigationController = operation.navigationType.getNavigationController(), navigationController == MVMCoreUISplitViewController.main()?.navigationController, let viewController = navigationController.viewControllers.last, let traversedController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift index b2c3d42c..49a3d5e9 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift @@ -57,6 +57,8 @@ import SafariServices @MainActor open func openURL(inSafariWebView url: URL) { let safariViewController = SFSafariViewController(url: url) - MVMCoreNavigationHandler.shared()?.present(safariViewController, animated: true) + Task(priority: .high) { + await NavigationHandler.shared().present(viewController: safariViewController) + } } } diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift b/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift index ffb74ef9..e04de6bb 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift +++ b/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift @@ -7,7 +7,7 @@ // import UIKit - +import MVMCore public extension MVMCoreUIUtility { @@ -66,3 +66,25 @@ public extension MVMCoreUIUtility { return nil } } + +@objc +public extension MVMCoreUIUtility { + @objc @MainActor + static func getVisibleViewController() -> UIViewController? { + var viewController = NavigationHandler.shared().getViewControllerToPresentOn() + while let presentedController = viewController?.presentedViewController, + !presentedController.isBeingDismissed { + viewController = presentedController + } + if let navigationController = viewController as? UINavigationController { + viewController = navigationController.topViewController + } + if let viewController = viewController { + return getViewControllerTraversingManagers(viewController) + } else if let viewController = MVMCoreUISession.sharedGlobal()?.navigationController?.topViewController { + return getViewControllerTraversingManagers(viewController) + } else { + return nil + } + } +} diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility.m b/MVMCoreUI/Utility/MVMCoreUIUtility.m index e99a6383..ad7366df 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility.m +++ b/MVMCoreUI/Utility/MVMCoreUIUtility.m @@ -51,19 +51,10 @@ } + (UIViewController *)getCurrentVisibleController { - UIViewController *baseViewController = [MVMCoreNavigationHandler sharedNavigationHandler].viewControllerToPresentOn ?: [MVMCoreGetterUtility getKeyWindow].rootViewController; - UIViewController *viewController = nil; - while (baseViewController.presentedViewController && !baseViewController.presentedViewController.isBeingDismissed) { - viewController = baseViewController.presentedViewController; - baseViewController = viewController; - } - if ([viewController isKindOfClass:[UINavigationController class]]) { - viewController = ((UINavigationController *)viewController).topViewController; - } - // if it is not presented viewcontroller, existing BAU logic will be working - if (!viewController) { - viewController = [self getViewControllerTraversingManagers:[MVMCoreUISession sharedGlobal].navigationController.topViewController]; - } + __block UIViewController *viewController = nil; + [MVMCoreDispatchUtility performSyncBlockOnMainThread:^{ + viewController = [self getVisibleViewController]; + }]; return viewController; }