如何在NavigationController栈中查找指定类型的首个ViewController并直接返回?
优雅查找导航栈中指定类型的首个ViewController
嘿,这个痛点我太熟悉了——在导航栈里找特定类型的ViewController,每次找到后还要手动强转确实有点啰嗦,而且你提到的flatMap方案确实存在遍历全栈、可读性差的问题,我来分享几个更优雅的解决办法!
基础优化方案:利用first(where:)短路查找+自动类型推断
Swift的first(where:)方法会在找到第一个符合条件的元素后立即停止遍历,完美解决flatMap全遍历的性能问题。同时我们可以结合类型检查,让强转操作更自然:
// 假设要查找的目标类型是TargetViewController if let targetVC = navigationController?.viewControllers.first(where: { $0 is TargetViewController }) as? TargetViewController { // 这里的targetVC已经是TargetViewController类型,直接使用即可 print("找到目标VC:\(targetVC)") }
这个写法虽然还有一次强转,但胜在逻辑清晰,而且是短路遍历,性能比flatMap好很多。
更优方案:封装成UINavigationController扩展
如果项目里经常需要做这个操作,最好把逻辑封装成扩展,这样代码复用性和可读性都会大幅提升:
import UIKit extension UINavigationController { /// 查找导航栈中首个指定类型的ViewController /// - Parameter type: 目标ViewController的类型 /// - Returns: 首个匹配类型的VC实例(无匹配则返回nil) func firstViewController<T: UIViewController>(ofType type: T.Type) -> T? { return viewControllers.first(where: { $0 is T }) as? T } }
调用的时候就超级清爽了,完全不用手动强转:
if let targetVC = navigationController?.firstViewController(ofType: TargetViewController.self) { // 直接使用targetVC,类型安全且无冗余代码 targetVC.doSomething() }
为什么这个方案比flatMap好?
- 性能更优:
first(where:)是短路遍历,找到第一个匹配项就停止,不会遍历整个导航栈;而flatMap会处理数组里的每一个元素 - 可读性更强:不管是基础写法还是扩展封装,逻辑都一目了然,其他开发者一看就知道是在找指定类型的首个VC
- 类型安全:完全避免了冗余的强制转换,编译器会帮我们做好类型检查,减少潜在的类型错误
内容的提问来源于stack exchange,提问作者Mark A. Donohoe
相关产品推荐
相关产品推荐

