ONEAPP-5208: Swiftify the navigation handler

This commit is contained in:
Scott Pfeil 2023-08-21 17:03:49 -04:00
parent 8ab996d8f8
commit ba8aa92994
10 changed files with 79 additions and 55 deletions

View File

@ -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)

View File

@ -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
}
}

View File

@ -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 }

View File

@ -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 <MVMCoreUIDetailViewProtocol> *)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 {

View File

@ -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()

View File

@ -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 {

View File

@ -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 }

View File

@ -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)
}
}
}

View File

@ -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
}
}
}

View File

@ -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;
}