// // TabNavigationController.swift // suixinkan // import UIKit @MainActor /// 单个 Tab 的 UIKit 导航栈,负责承载该 Tab 内部页面层级。 final class TabNavigationController: UINavigationController { let appTab: AppTab private let services: AppServices /// 初始化实例。 init(tab: AppTab, services: AppServices) { self.appTab = tab self.services = services super.init(nibName: nil, bundle: nil) delegate = self navigationBar.prefersLargeTitles = false setViewControllers([tab.makeRootViewController(services: services)], animated: false) } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } /// Push 指定应用路由,并统一设置底部 TabBar 隐藏策略。 func push(route: AppRoute, animated: Bool = true) { let viewController = AppRouteViewControllerFactory.makeViewController(for: route, services: services) viewController.hidesBottomBarWhenPushed = route.hidesTabBarWhenPushed pushViewController(viewController, animated: animated) } /// Push 页面时按目标页同步系统导航栏状态,覆盖各页面直接调用系统 push 的场景。 override func pushViewController(_ viewController: UIViewController, animated: Bool) { updateNavigationBarVisibility(for: viewController, animated: animated) super.pushViewController(viewController, animated: animated) } /// 设置导航栈时按最终栈顶同步系统导航栏状态。 override func setViewControllers(_ viewControllers: [UIViewController], animated: Bool) { if let topViewController = viewControllers.last { updateNavigationBarVisibility(for: topViewController, animated: animated) } super.setViewControllers(viewControllers, animated: animated) } /// 弹出页面后按新的栈顶同步系统导航栏状态。 override func popViewController(animated: Bool) -> UIViewController? { let poppedViewController = super.popViewController(animated: animated) if !animated, let topViewController { updateNavigationBarVisibility(for: topViewController, animated: false) } return poppedViewController } /// 回到根页面后按根页面同步系统导航栏状态。 override func popToRootViewController(animated: Bool) -> [UIViewController]? { let poppedViewControllers = super.popToRootViewController(animated: animated) if !animated, let topViewController { updateNavigationBarVisibility(for: topViewController, animated: false) } return poppedViewControllers } /// 弹到指定页面后按该页面同步系统导航栏状态。 override func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? { let poppedViewControllers = super.popToViewController(viewController, animated: animated) if !animated, let topViewController { updateNavigationBarVisibility(for: topViewController, animated: false) } return poppedViewControllers } /// 根据页面类型判断系统导航栏是否应隐藏。 private func shouldHideNavigationBar(for viewController: UIViewController) -> Bool { viewController is HomeViewController } /// 将系统导航栏显示状态同步到目标页面,避免首页隐藏状态泄漏到子页面。 private func updateNavigationBarVisibility(for viewController: UIViewController, animated: Bool) { setNavigationBarHidden(shouldHideNavigationBar(for: viewController), animated: animated) } } extension TabNavigationController: UINavigationControllerDelegate { /// 导航转场即将展示页面时更新系统导航栏显隐状态。 func navigationController( _ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool ) { updateNavigationBarVisibility(for: viewController, animated: animated) } }