Created
March 26, 2017 11:16
-
-
Save ManWithBear/4b2238f6776f27548a0142fe681b53ca to your computer and use it in GitHub Desktop.
Loading objects from Nib
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// If you want to create some common way to load objects from nibs, you will probably try something like that: | |
protocol NibLoadable: class { | |
static func fromNib() -> Self? | |
static func nibName() -> String | |
} | |
extension NibLoadable { | |
static func nibName() -> String { | |
return String(describing: Self.self) | |
} | |
static func fromNib() -> Self? { | |
let nibContent = Bundle(for: Self.self).loadNibNamed(nibName(), owner: nil, options: nil) | |
return nibContent?.first { $0 is Self } as? Self | |
} | |
} | |
extension UIView: NibLoadable { } | |
// But oups! | |
// Method 'fromNib()' in non-final class 'UIView' must return `Self` to conform to protocol 'NibLoadable' | |
// So what happend? | |
// UIView and all of its subclasses are adopting the NibLoadable protocol. It means, for UIView, that there will be | |
// method static func fromNib() -> UIView? | |
// Every UIView's subclasses will inherit this method, but protocol confirmance inherited too and expect | |
// static func fromNib() -> ChildView? method. So any subclass will violate protocol confirmance. | |
// So, should I create this function by hands for every class I want to load from nib? | |
// No! Here another generic solution, but not so elegant as protocol with default implementation: | |
func loadFromNib<T: AnyObject>(named nibName: String = String(describing: T.self)) -> T? { | |
let nibContent = Bundle(for: T.self).loadNibNamed(nibName, owner: nil, options: nil) | |
return nibContent?.first { $0 is T } as? T | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment