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

3

我写了一个函数,它通过迭代给定UIView的superviews来获取对特定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
}
3个回答

8
像这样吗?
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!)
        }
    }
}

使用 "Nil Coalescing Operator"flatMap(_:) 方法,在 Optional 枚举上。


就是这样!我知道它会更简洁。你能否详细解释一下?我在理解代码方面有些概念上的问题。 - rustproofFish
谢谢!当你看到扩展版本时,这是显而易见的。使用 flatmap() 使我感到困惑,但现在我意识到它是处理当你运行超出 superviews 时的 nil 事件的一种巧妙方式。 - rustproofFish

4

Swift使用泛型查找给定类的父视图

适用于Swift 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)

3

编辑:这是用于搜索视图而不是超级视图的。

您可以尝试使用递归函数方法而不是while循环。不知道这是否符合您的要求。

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
}

编辑2 + 3: 简化了函数


我确实考虑过这个问题,因为它似乎很适合解决它,但我发现这实际上使我的代码稍微臃肿和难以阅读。我在想是否可以使用递归的“管道”(如果有意义的话):获取父视图->如果没有视图,则返回nil->否则,如果有父视图,则返回父视图并重复。我不确定我是否表达清楚,因为我对术语不是很熟悉。谢谢你的建议。 - rustproofFish
哦,我刚意识到你想搜索“上”而不是“下”。 - eyeballz
没问题 :-) 无论如何谢谢。 - rustproofFish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接