簡體   English   中英

水平流 iOS 12 中的 TabbarCoordinator 中未調用后退按鈕

[英]Back button not being called in TabbarCoordinator in horizontal flow iOS 12

協調器模式是一個古老的話題,許多庫試圖解決它,我正在簡單的示例應用程序中學習它。 我當前的設置是 3 個 rootViewControlers: LoadingStateCoordinatorWelcomeCoordinatorTabBarCoordinator但缺少 UIKit 和協調器之間的連接。 我正在嘗試使用 UINavigationController 來實現它,但沒有調用該按鈕。 我需要一種連接到后退按鈕的方法和一個可重用的協調器,我可以將其推送到並相應地解除分配(即沒有 RxSwift)。*將歡迎屏幕設置為父/主導航,並且始終能夠返回它。* * 因此,在用戶從顯示的模態視圖(垂直流)中選擇一個表單后,我會在推送時顯示一個 TabBarCoordinator(水平)。 所有的 viewController 都有空的.storyboard , UIViewController 和 Coordinator 除了 TabBar。這里我只有一個協調器,因為設置了子選項卡協調器,並且需要在后退按鈕點擊時發生魔法。 目前只有當用戶來自 LoadingStateCoordinator 時才會調用它。 在那里我需要將用戶發送回歡迎屏幕,以便他們可以更改入職設置。 這是 LoadingStateCoordinator 的第一個代碼:

final class LoadingStateCoordinator: NSObject, Coordinator {
    *// MARK: - Inputs required*

    var childCoordinators: [Coordinator]
    var presenter: UINavigationController
    private let window: UIWindow

    *// MARK: - Initialization*
    init(window: UIWindow) {
        self.window = window
        childCoordinators = []
        presenter = UINavigationController()
    }
    *// MARK: - Coordinator*
     func start() {
        let controller: LoadingStateViewController = LoadingStateViewController.instantiate()
        window.rootViewController = controller
        controller.delegate = self
        }

}
    *// MARK: - LoadingViewControllerDelegate*
extension LoadingStateCoordinator : LoadingViewControllerDelegate {
    func performScreenSwitch() {
        if UserDefaults.standard.userWasHere == false {
            let tabCoordinator: TabBarCoordinator = TabBarCoordinator(window: window, tabBarController: UITabBarController())
            window.rootViewController = presenter
            addChildCoordinator(tabCoordinator)
            tabCoordinator.start()
            presenter.pushViewController(tabCoordinator.tabBarController!, animated: true)

        } else {
            let welcomeCoordinator = WelcomeCoordinator(window: window, presenter: presenter)
            window.rootViewController = welcomeCoordinator.presenter
            addChildCoordinator(welcomeCoordinator)
            welcomeCoordinator.start()
        }
    }
}

這是需要執行返回歡迎屏幕操作的 TabBarCoordinator。 當我展示popToRoot功能時,它會推送歡迎屏幕,但那里的所有按鈕都被禁用。 我猜是保留周期問題。 我需要另一種設置嗎? 有沒有辦法在這個設置中 popToRoot(vc) ? 我嘗試以運行時錯誤“彈出到非現有控制器”結束。 需要執行此操作的 TabBarCoordinator 代碼:

final class TabBarCoordinator: NSObject, Coordinator {
    internal var presenter: UINavigationController
    internal var tabBarController: UITabBarController?
    internal var childCoordinators: [Coordinator]
    var parentCoordinator: LoadingStateCoordinator?
    lazy var leftBtn: UIBarButtonItem = {
        let button = UIButton(type: .system)
        button.setImage(UIImage(systemName: "arrow.turn.up.left"), for: .normal)
        button.sizeToFit()
        button.addTarget(self,
                         action: #selector(self.popToRoot(_:)),
                         for: .touchUpInside)
      return UIBarButtonItem(customView: button)
    }()

    init(window: UIWindow, tabBarController: UITabBarController) {
        self.tabBarController = tabBarController
        childCoordinators = []
        self.presenter = UINavigationController()

    }
     func start() {
        performGetTabBar()
        self.presenter.delegate = self
    }
    private func performGetTabBar() {
        let coordinators: [Coordinator] = generateTabCoordinators()

        coordinators.forEach({ coordinator in
            coordinator.start()
            addChildCoordinator(coordinator)
        })

        let presenters: [UIViewController] = coordinators.map({ coordinator -> UIViewController in
            return coordinator.presenter
        })
        leftBtn.style = .plain
        tabBarController?.navigationItem.leftBarButtonItem = leftBtn
        tabBarController?.setViewControllers(presenters, animated: false)
        selectTab(type: SurfTripCoordinator.self)
    }

    private func generateTabCoordinators() -> [Coordinator] {
        let calculatorCoordinator: CalculatorCoordinator = CalculatorCoordinator(presenter: UINavigationController())
        let tripCoordinator: SurfTripCoordinator = SurfTripCoordinator(presenter: UINavigationController())
        let sellCoordinator: SavedTripsCoordinator = SavedTripsCoordinator(presenter: UINavigationController())
        return [calculatorCoordinator, tripCoordinator, sellCoordinator]
    }
    *//this is not being called when coming from vertical flow*
    @objc func popToRoot(_ sender: UIBarButtonItem) {
        let storyboard: UIStoryboard = UIStoryboard(name: Constants.Storyboards.welcomeViewCoordinator, bundle: nil)
        let controller: WelcomeViewController = WelcomeViewController.instantiate(from: storyboard)
        tabBarController?.navigationController?.pushViewController(controller, animated: true)

    }
}

extension TabBarCoordinator: UINavigationControllerDelegate {

    func selectTab<T: Coordinator>(type _: T.Type) {
        guard let index = childCoordinators.firstIndex(where: { coordinator in
            coordinator is T
        }) else {
            return
        }
        tabBarController?.selectedIndex = index
  }
}

這是當前的 WelcomeCoordinator 設置

class WelcomeCoordinator: NSObject, Coordinator {
    internal var presenter: UINavigationController
    var childCoordinators: [Coordinator]

    init(window: UIWindow, presenter: UINavigationController) {
        self.presenter = presenter
        childCoordinators = []

    }
    func start() {
        let storyboard: UIStoryboard = UIStoryboard(name: Constants.Storyboards.welcomeViewCoordinator, bundle: nil)
        let controller: WelcomeViewController = WelcomeViewController.instantiate(from: storyboard)
        controller.delegate = self
        presenter.pushViewController(controller, animated: true)
    }
}

extension WelcomeCoordinator : WelcomeViewControllerDelegate {

    func performAddLevel() {
        let addLevelCoordinator: AddLevelViewCoordinator = AddLevelViewCoordinator(presenter: UINavigationController())
        addLevelCoordinator.start()
        addChildCoordinator(addLevelCoordinator)
        addLevelCoordinator.presenter.modalPresentationStyle = .fullScreen
        presenter.present(addLevelCoordinator.presenter, animated: true, completion: nil)
    }
}

對不起,我希望有更多的本地方式來做到這一點......

好的,所以我找到了部分解決方案,即我的案例的后退按鈕解決方案:不使用pushViewControllershow因為它帶有后退按鈕。 presenter.setViewControllers([tabCoordinator.tabBarController!], animated: true)然后將導航欄設置為隱藏。 我制作了自己的 navItem 按鈕來導航到 rootVC。 下一步分配和刪除所有子 tabBar 協調器識別后點擊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM