Skip to content

Instantly share code, notes, and snippets.

@martin-lalev
Last active December 23, 2022 09:37
Show Gist options
  • Save martin-lalev/7113847a33484dd99ca366a4a0a0e411 to your computer and use it in GitHub Desktop.
Save martin-lalev/7113847a33484dd99ca366a4a0a0e411 to your computer and use it in GitHub Desktop.
Lightweight DSL for defining UIView hierarchy using Swift 5.1's function builders.
protocol UIViewArrayConvertible {
func items() -> [UIView]
}
extension UIView: UIViewArrayConvertible {
func items() -> [UIView] { [self] }
}
extension Array: UIViewArrayConvertible where Element: UIView {
func items() -> [UIView] { self }
}
@_functionBuilder
struct UIViewBuilder {
static func buildBlock(_ components: UIViewArrayConvertible ...) -> UIViewArrayConvertible { components.flatMap { $0.items() } }
static func buildIf(_ component: UIViewArrayConvertible?) -> UIViewArrayConvertible { component ?? [UIView]() }
static func buildEither(first: UIViewArrayConvertible) -> UIViewArrayConvertible { first }
static func buildEither(second: UIViewArrayConvertible) -> UIViewArrayConvertible { second }
}
extension UIView {
@discardableResult
func addSubviews(@UIViewBuilder _ viewBuilder: () -> UIViewArrayConvertible) -> UIView {
for view in viewBuilder().items() {
self.addSubview(view)
}
return self
}
}
extension UIViewController {
@discardableResult
func addSubviews(@UIViewBuilder _ viewBuilder: () -> UIViewArrayConvertible) -> UIView {
for view in viewBuilder().items() {
self.view.addSubview(view)
}
return self.view
}
}
@martin-lalev
Copy link
Author

Usage example:

self.view.addSubviews {
    self.background
    self.container.addSubviews {
        self.icon
        self.labelsContainer.addSubviews {
            self.title
            self.subTitle
        }
        if self.isFavorite {
            self.starFilledIndicator
        } else {
            self.starStrokedIndicator
        }
        self.button
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment