NSDictionaryOfVariableBindings for Swift
This file contains 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
/** | |
* NSDictionaryOfVariableBindings for Swift | |
* | |
* In Objective-C you could use macros to quickly get a Dictionary of views, | |
* keyed on their names in the sourcecode. Like so: | |
* | |
* UILabel *label = [UILabel autolayoutView]; | |
* NSDictionary *views = NSDictionaryOfVariableBindings(label); | |
* | |
* Which you could then use in, for example, VFL: | |
* | |
* H:|-[label]-| | |
* | |
* In Swift `NSDictionaryOfVariableBindings` is not available anymore. | |
* | |
* But we can use reflection to accomplish something similar in Swift. It | |
* happens at runtime, so it is much slower, but yet. So how does this work? | |
* In custom views or VCs you usually have a bunch of instance variables for | |
* the subviews you use. | |
* | |
* class MyTableViewCell : UITableViewCell, ZzViewHolder { // <=== | |
* let label = UILabel() | |
* let button = UIButton() | |
* | |
* override init(style: UITableViewCellStyle, reuseIdentifier: String?) { | |
* super.init(style: style, reuseIdentifier: reuseIdentifier) | |
* | |
* allViews.forEach { // <=== | |
* $0.translatesAutoresizingMaskIntoConstraints = false | |
* addSubview($0) | |
* } | |
* | |
* NSLayoutConstraint.activate(NSLayoutConstraint.constraints( | |
* withVisualFormat: "H:|-[label]-[button]-|", | |
* options: [], metrics: nil, | |
* views: idToViews // <=== | |
* )) | |
* } | |
* } | |
*/ | |
public protocol ZzViewHolder { | |
// just a mixin protocol | |
} | |
public extension ZzViewHolder { | |
public var allViews : [ ZzView ] { | |
return Mirror(reflecting: self).children.flatMap { $0.1 as? ZzView } | |
} | |
public var idToView : [ String : ZzView ] { | |
// Unfortunately in Swift, we cannot return a trampoline because VFL API | |
// expects a [:], not an arbitrary Map protocol. | |
var idToView = [ String : ZzView ]() | |
for ( key, value ) in Mirror(reflecting: self).children { | |
guard let key = key, let view = value as? ZzView else { continue } | |
idToView[key] = view | |
} | |
return idToView | |
} | |
} | |
#if os(macOS) | |
public typealias ZzView = NSView | |
#else | |
public typealias ZzView = UIView | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment