使用函数式Swift搜索UIView层次结构



我写了一个函数,通过一个给定的UIView的父视图迭代,以获得一个特定的UIView子类的引用,如果存在(在这种情况下,UITableView)。使用命令式风格可以很好地工作,但它似乎确实是一个问题,将借给自己很好地"面向铁路的编程"。由于我还在思考函数式的问题,有人能提出这个函数更优雅的函数式版本吗?

func findTableView(var view: UIView) -> UITableView? {
    var table: UITableView? = nil
    while table == nil {
        guard let superView = view.superview else { return nil }
        view = superView
        table = view as? UITableView
    }
    return table
}

像这样?

func findTableView(view: UIView) -> UITableView? {
    return view as? UITableView ?? view.superview.flatMap(findTableView)
}

这段代码只是:

func findTableView(view: UIView) -> UITableView? {
    if let tableView = view as? UITableView {
        return tableView
    }
    else {
        let superview = view.superview
        if superview == nil {
            return nil
        }
        else {
            return findTableView(superview!)
        }
    }
}

Optional enum上使用"Nil聚结算子"和flatMap(_:)方法。

快速查找泛型类的父类

迅速3/4

extension UIView {
    func superview<T>(of type: T.Type) -> T? {
        return superview as? T ?? superview.compactMap { $0.superview(of: type) }
    }
    func subview<T>(of type: T.Type) -> T? {
        return subviews.compactMap { $0 as? T ?? $0.subview(of: type) }.first
    }
}

用法:

let tableView = someView.superview(of: UITableView.self)
let tableView = someView.subview(of: UITableView.self)

Edit:这是用于搜索视图而不是超级视图

你可以马上尝试递归函数方法。不知道这是不是你想要的

func findTableView(view: UIView) -> UITableView? {
    if view is UITableView {
        return view as? UITableView
    } else {
        for subview in view.subviews {
            if let res = findTableView(subview) {
                return res
            }
        }
    }
    return nil
}

Edit 2 + 3:使函数更简单

最新更新