Skip to content

Instantly share code, notes, and snippets.

@Adobels
Created May 31, 2023 05:54
Show Gist options
  • Save Adobels/ae4137a8cc3cb7c688d7ade945a7dda3 to your computer and use it in GitHub Desktop.
Save Adobels/ae4137a8cc3cb7c688d7ade945a7dda3 to your computer and use it in GitHub Desktop.
UIKitView builder + constraints
//
// ViewController.swift
// pocUIViewBuilder
//
// Created by MaxAir on 26/05/2023.
//
import UIKit
@resultBuilder
struct SubviewBuilder {
static func buildEither(first component: UIView) -> UIView {
print(#function + "2")
return component
}
static func buildEither(second component: UIView) -> UIView {
print(#function + "1")
return component
}
static func buildBlock(_ components: UIView...) -> UIView {
print(#function + "2" + components.map { $0.tag }.description)
let view = IfBlockView()
components.forEach { view.addSubview($0) }
return view
}
static func buildBlock(_ components: UIView...) -> [UIView] {
print(#function + "1" + components.map { $0.tag }.description)
let result = components.flatMap {
if $0 is IfBlockView {
return $0.subviews
} else {
return [$0]
}
}
return result
}
static func buildOptional(_ component: UIView?) -> UIView {
print(#function + "2" + (component?.description ?? "-") ?? "-")
return component ?? UIView()
}
static func buildIf(_ component: UIView?) -> [UIView] {
print(#function)
switch component {
case .none:
return []
case .some(let wrapped):
return [wrapped]
}
}
}
class IfBlockView: UIView { }
extension UIView {
@discardableResult
func addSubviews(@SubviewBuilder builder: () -> [UIView]) -> UIView {
builder().forEach { addSubview($0) }
return self
}
convenience init(tag: Int) {
self.init(frame: .zero)
self.tag = tag
}
@discardableResult
func configureConstraints(_ builder: (_ outlet: UIView) -> [NSLayoutConstraint]) -> Self {
let constraints = builder(self)
constraints.forEach { $0.isActive = true }
self.addConstraints(constraints)
return self
}
}
extension UIStackView {
convenience init(axis: NSLayoutConstraint.Axis) {
self.init()
self.axis = .horizontal
self.axis = axis
}
}
extension UIView {
func outlet<T: UIView>(_ outlet: inout T?) -> Self {
outlet = self as? T
return self
}
}
class ViewController: UIViewController {
var stackView: UIStackView!
var labelTitle: UILabel!
var labelOne: UILabel!
var labelTwo: UILabel!
var labelThree: UILabel!
var labelFour: UILabel!
var labelFive: UILabel!
var buttonMain: UIButton!
var cell: UITableViewCell!
override func viewDidLoad() {
super.viewDidLoad()
createView()
configureAutoLayout()
}
private func createView() {
view.addSubviews {
UIStackView(axis: .horizontal).outlet(&stackView).addSubviews {
if true {
UILabel().outlet(&labelTitle).configureConstraints { outlet in
[
outlet.widthAnchor.constraint(equalToConstant: 20),
outlet.heightAnchor.constraint(equalToConstant: 10),
]
}
}
UILabel().outlet(&labelOne)
UIButton(primaryAction: .init(handler: { _ in
print("")
})).outlet(&buttonMain)
UIButton(type: .contactAdd).outlet(&buttonMain)
UILabel().outlet(&labelTwo)
if true {
UILabel().outlet(&labelThree)
}
}.configureConstraints { outlet in
[
outlet.widthAnchor.constraint(equalToConstant: 20),
outlet.heightAnchor.constraint(equalToConstant: 10),
]
}
}
}
private func configureAutoLayout() {
labelTitle.configureConstraints { outlet in
[
outlet.widthAnchor.constraint(equalToConstant: 20),
outlet.heightAnchor.constraint(equalToConstant: 10),
]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment