swift - 你们都可以在集合中找到一个类型的第一个实例,并将该实例作为具体类型返回吗?

标签 swift casting flatmap

这段代码让我很困扰。下面,我试图在 NavigationController 的堆栈中找到特定类型的 ViewController 的第一个实例。简单的。但是当我找到它时,我必须将它转换为我刚刚寻找的类型,这对我来说似乎是多余的。

func popToFirstViewController<T:UIViewController>(ofType type:T.Type, animated:Bool) -> T? {

    guard let foundViewController = viewControllers.first(where: { $0 is T }) as? T else {
        return nil
    }

    self.popToViewController(foundViewController, animated:animated)

    return foundViewController
}

我唯一能想到的就是这个......

func popToFirstViewController<T:UIViewController>(ofType type:T.Type, animated:Bool) -> T? {

    guard let foundViewController = viewControllers.flatMap({ $0 as? T }).first() else {
        return nil
    }

    self.popToViewController(foundViewController, animated:animated)

    return foundViewController
}

...但我反复发现像这样使用 flatMap 会使阅读代码的人感到困惑,并且正如下面评论中正确指出的那样,它会遍历整个集合,而 first 不会那样做。

那么还有其他方法可以解决这个问题吗?

最佳答案

您可以使用case patterns 来选择您感兴趣的类型的 viewController,然后弹出并返回您找到的第一个:

extension UINavigationController {
    func popToFirstViewController<T:UIViewController>(ofType type:T.Type, animated:Bool) -> T? {

        for case let vc as T in viewControllers {
            self.popToViewController(vc, animated: animated)
            return vc
        }

        return nil
    }
}

示例:

使用 OrangeViewController 中的按钮返回堆栈中较早的 GreenViewController:

@IBAction func popToGreen(_ sender: UIButton) {
     let greenVC = self.navigationController?.popToFirstViewController(
           ofType: GreenViewController.self,
         animated: true
     )

     // Modify a property in GreenViewController that
     // will be moved into a label in viewWillAppear      
     greenVC?.labelText = "Returned here from Orange"
}

popToLastViewController(ofType:animated:)

您可能还希望一个函数弹出到某个类型的最新 viewController。这很容易通过简单的修改实现(添加 .reversed()):

func popToLastViewController<T:UIViewController>(ofType type:T.Type, animated: Bool) -> T? {

    for case let vc as T in viewControllers.reversed() {
        self.popToViewController(vc, animated: animated)
        return vc
    }

    return nil
}

关于swift - 你们都可以在集合中找到一个类型的第一个实例,并将该实例作为具体类型返回吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49162574/

相关文章:

swift - 在 Swift 中使用来自 Web 服务的 NSXMLParser 解析 SOAP 响应

html - 在 Swift 中解析 HTML 字符串

ios - 如何从导航 Controller 转换回 VC?

java - Java 使用 Scanner with double 时出错

java-8 - 使用 Java 8 Streams 创建和反转 MultiMap

ios - 如何隐藏导航 Controller 堆栈中单个 View Controller 的选项卡栏

c - 为什么转换这个指针也会改变指向的值

使用通用接口(interface)的 C# 转换

Angular 2 - 当返回一个空的可观察对象时,使用平面图的同步 http 调用不执行下一个调用

java - flatMap 保证是惰性的吗?