rob5408 rob5408 - 7 months ago 24
Swift Question

Using 'self' in class extension functions in Swift

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 of MyCustomView. I'm almost ready to just port the working Objective-C code I have via the bridging header, but figured I'd try the idiomatic approach first. That was two hours ago.

extension UIView {
class func instantiateFromNib() -> Self? {

let topLevelObjects = NSBundle.mainBundle().loadNibNamed("CustomViews", owner: nil, options: nil)

for topLevelObject in topLevelObjects {
if (topLevelObject is self) {
return topLevelObject
}
}

return nil
}
}


Now
if (topLevelObject is self) {
is wrong because "Expected type after 'is'". What I've tried after that shows a lot about what I don't understand about the Swift type system.


  • if (topLevelObject is Self) {

  • if (topLevelObject is self.dynamicType) {

  • if (topLevelObject is self.self) {

  • A million other variations that are not even wrong.



Any insight is appreciated.

Answer

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>() -> 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.

Comments