能否在不影响旧代码前提下重写/重载UIViewController静态查找控制器方法?
解决方案
问题根源
原findBestVC方法未处理UIPageViewController类型的控制器,当遇到MainViewController嵌套UIPageViewController的层级时,无法递归进入UIPageViewController内部查找顶层控制器,直接返回了MainViewController。
修改方案(兼容旧代码)
直接在原扩展的静态方法中新增UIPageViewController的处理分支,无需重写/重载方法(原方法的调用逻辑完全不变,所有跨模块的旧代码无需修改)。
修改后的完整代码:
public extension UIViewController { static func findBestVC(from viewController: UIViewController) -> UIViewController { if let presentedVC = viewController.presentedViewController { return findBestVC(from: presentedVC) } else if let splitVC = viewController as? UISplitViewController { if let lastVC = splitVC.viewControllers.last { return findBestVC(from: lastVC) } } else if let pageVC = viewController as? UIPageViewController { // 处理UIPageViewController,取当前显示的控制器(通常是viewControllers数组的第一个) if let currentVC = pageVC.viewControllers?.first { return findBestVC(from: currentVC) } } else if let navVC = viewController as? UINavigationController { if let topVC = navVC.topViewController { return findBestVC(from: topVC) } } else if let tabVC = viewController as? UITabBarController { if let topVC = tabVC.moreNavigationController.topViewController, topVC.view.window != nil { return findBestVC(from: topVC) } else if let selectedVC = tabVC.selectedViewController { return findBestVC(from: selectedVC) } } return viewController } }
关键说明
- 新增的
UIPageViewController分支会优先检查当前页面控制器的显示内容,递归进入其内部的NavigationController,最终找到顶层的ViewController A/B。 - 原有的
UITabBarController、UINavigationController等处理逻辑完全保留,旧视图层级的代码不受任何影响。 - 若
UIPageViewController的viewControllers为空(极端情况),则返回自身,保证方法的安全性。
额外优化建议
如果你的UIPageViewController存在多页面同时显示的场景(比如某些自定义布局),可以根据实际逻辑调整获取当前控制器的方式,例如通过pageVC.dataSource或自定义属性跟踪当前选中的控制器,但大部分标准场景下取viewControllers?.first即可满足需求。
内容的提问来源于stack exchange,提问作者sonle
相关产品推荐
相关产品推荐

