Skip to content

Instantly share code, notes, and snippets.

@JadenGeller
Last active December 24, 2015 22:49
Show Gist options
  • Save JadenGeller/dc5de801acce062b9439 to your computer and use it in GitHub Desktop.
Save JadenGeller/dc5de801acce062b9439 to your computer and use it in GitHub Desktop.
Interpolated Visual Constraint Language
// Example
let blueView = UIView()
blueView.backgroundColor = UIColor.blueColor()
blueView.translatesAutoresizingMaskIntoConstraints = false
let greenView = UIView()
greenView.backgroundColor = UIColor.greenColor()
greenView.translatesAutoresizingMaskIntoConstraints = false
let redView = UIView()
redView.backgroundColor = UIColor.redColor()
redView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(blueView)
view.addSubview(greenView)
view.addSubview(redView)
let size = 60
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-[\(blueView)(\(size))]-[\(redView)(==\(greenView))]-[\(greenView)(==\(redView))]-|"))
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[\(redView)(\(size))]-[\(greenView)(==\(blueView))]-[\(blueView)(==\(greenView))]-|"))
// BAM! https://pbs.twimg.com/media/CIaWFfqUMAE307B.png:large
// Implementation
struct ConstraintBuilder : StringInterpolationConvertible {
let format: String
let metrics: [String : NSNumber]
let views: [String : UIView]
init(stringInterpolation strings: ConstraintBuilder...) {
format = "".join(strings.map{ $0.format })
metrics = strings.map{ $0.metrics }.reduce([String : NSNumber]()){ $0 + $1 }
views = strings.map{ $0.views }.reduce([String : UIView]()){ $0 + $1 }
}
init<T>(stringInterpolationSegment expr: T) {
format = "\(expr)"
metrics = [String : NSNumber]()
views = [String : UIView]()
}
init(stringInterpolationSegment expr: UIView) {
format = uniqueName(expr)
metrics = [String : NSNumber]()
views = [format : expr]
}
init(stringInterpolationSegment expr: NSNumber) {
format = expr.stringValue
metrics = [format : expr]
views = [String : UIView]()
}
}
extension NSLayoutConstraint {
static func constraintsWithVisualFormat(builder: ConstraintBuilder, options: NSLayoutFormatOptions = []) -> [NSLayoutConstraint] {
return constraintsWithVisualFormat(builder.format, options: options, metrics: builder.metrics, views: builder.views)
}
}
// Helpers
func memoryAddress(object: AnyObject) -> String {
return Unmanaged.passUnretained(object).toOpaque().debugDescription
}
func uniqueName(object: AnyObject) -> String {
return String(memoryAddress(object).characters.map { char in
switch char {
case "0": return "A"
case "1": return "B"
case "2": return "C"
case "3": return "D"
case "4": return "E"
case "5": return "F"
case "6": return "G"
case "7": return "H"
case "8": return "I"
case "9": return "J"
default: return char
}
})
}
func +<K,V>(var lhs: Dictionary<K,V>, rhs: Dictionary<K,V>) -> Dictionary<K,V> {
for (key, value) in rhs {
lhs.updateValue(value, forKey: key)
}
return lhs
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment