Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift find superview of given class with generics

I guess I'm struggling with generics. I want to create simple UIView extension to find recursively a superview of class passed in the function param. I want the function to return optional containing obviously either nil, or object visible as instance of provided class.

extension UIView {
    func superviewOfClass<T>(ofClass: T.Type) -> T? {
        var currentView: UIView? = self

        while currentView != nil {
            if currentView is T {
                break
            } else {
                currentView = currentView?.superview
            }
        }

        return currentView as? T
    }
}

Any help much appreciated.

like image 307
Chris Rutkowski Avatar asked Jun 08 '16 14:06

Chris Rutkowski


2 Answers

Swift 3/4

This is a more concise way:

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
    }

}

Usage:

let tableView = someView.superview(of: UITableView.self)
let tableView = someView.subview(of: UITableView.self)
like image 77
efremidze Avatar answered Nov 15 '22 17:11

efremidze


No need to pass in the type of the class you want (at least in Swift 4.1)…

extension UIView {    
    func firstSubview<T: UIView>() -> T? {
        return subviews.compactMap { $0 as? T ?? $0.firstSubview() as? T }.first
    }
}
like image 38
Ashley Mills Avatar answered Nov 15 '22 18:11

Ashley Mills