Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Buttons with equal width using Visual Format Language
import UIKit
public extension UIView {
var autoLayout: AutoLayout {
return AutoLayout(self)
}
}
public struct AutoLayout {
public let base: UIView
public init(_ base: UIView) {
self.base = base
}
public func applyVisualFormatLanguage(constraints: [String],
options: NSLayoutConstraint.FormatOptions = [],
metrics: [String: Any]? = nil) {
base.translatesAutoresizingMaskIntoConstraints = false
var views = enumerateSubViews()
views["baseView"] = base
views.values.forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
constraints.forEach {
base.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: $0, options: options, metrics: metrics, views: views))
}
}
public func enumerateSubViews() -> [String: UIView] {
var views = [String: UIView]()
let mirror = Mirror(reflecting: base)
let addToViewsClosure: ((Mirror.Child) -> Void) = { child in
child.label.flatMap { label in
let key = label.replacingOccurrences(of: ".storage", with: "")
views[key] = child.value as? UIView
}
}
mirror.children.forEach(addToViewsClosure)
mirror.superclassMirror?.children.forEach(addToViewsClosure)
return views
}
}
final class Foo: LayoutView {
private let login = UIButton()
private let register = UIButton()
override func layout() {
super.layout()
autoLayout.applyVisualFormatLanguage(constraints: [
"H:[login(==register)]"
])
}
}
import UIKit
class LayoutView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
layout()
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
layout()
}
func layout() {
autoLayout.enumerateSubViews().values.forEach { addSubview($0) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment