Using 'self' in class extension functions in Swift

前端 未结 2 605
执念已碎
执念已碎 2020-11-28 14:14

I\'m looking to be able to pull out an instance of a UIView subclass from a Nib.

I\'d like to be able to call MyCustomView.instantiateFromNib() and have an instance

2条回答
  •  盖世英雄少女心
    2020-11-28 14:30

    Using the approach from How can I create instances of managed object subclasses in a NSManagedObject Swift extension? you can define a generic helper method which infers the type of self from the calling context:

    extension UIView {
    
        class func instantiateFromNib() -> Self? {
            return instantiateFromNibHelper()
        }
    
        private class func instantiateFromNibHelper() -> T? {
            let topLevelObjects = NSBundle.mainBundle().loadNibNamed("CustomViews", owner: nil, options: nil)
    
            for topLevelObject in topLevelObjects {
                if let object = topLevelObject as? T {
                    return object
                }
            }
            return nil
        }
    }
    

    This compiles and works as expected in my quick test. If MyCustomView is your UIView subclass then

    if let customView = MyCustomView.instantiateFromNib() {
        // `customView` is a `MyCustomView`
        // ...
    } else {
        // Not found in Nib file
    }
    

    gives you an instance of MyCustomView, and the type is inferred automatically.


    Update for Swift 3:

    extension UIView {
    
        class func instantiateFromNib() -> Self? {
            return instantiateFromNibHelper()
        }
    
        private class func instantiateFromNibHelper() -> T? {
            if let topLevelObjects = Bundle.main.loadNibNamed("CustomViews", owner: nil, options: nil) {
                for topLevelObject in topLevelObjects {
                    if let object = topLevelObject as? T {
                        return object
                    }
                }
            }
            return nil
        }
    }
    

提交回复
热议问题