51 lines
1.3 KiB
Swift
51 lines
1.3 KiB
Swift
//
|
|
// Box.swift
|
|
// Box
|
|
//
|
|
// Created by James Magahern on 7/13/21.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
struct Box<Identifier: Hashable> {
|
|
typealias Compartment = (Identifier, CGRect)
|
|
typealias Realized = (Identifier, UIView)
|
|
|
|
@resultBuilder
|
|
struct BoxBuilder {
|
|
static func buildEither(first component: [Compartment]) -> Compartment {
|
|
component[0]
|
|
}
|
|
|
|
static func buildEither(second component: [Compartment]) -> Compartment {
|
|
component[0]
|
|
}
|
|
|
|
static func buildBlock(_ compartments: Compartment...) -> [Compartment] {
|
|
return compartments
|
|
}
|
|
}
|
|
|
|
public var boundingRect: CGRect {
|
|
get {
|
|
compartmentMap.reduce(into: CGRect.zero) { (result, compartment) in
|
|
result = result.union(compartment.value)
|
|
}
|
|
}
|
|
}
|
|
|
|
private var compartmentMap: [Identifier: CGRect] = [:]
|
|
|
|
init(@BoxBuilder _ compartments: () -> [Compartment]) {
|
|
self.compartmentMap = compartments().reduce(into: [:]) { (result, compartment) in
|
|
result[compartment.0] = compartment.1
|
|
}
|
|
}
|
|
|
|
public func fill(_ realized: [Identifier: UIView]) {
|
|
realized.forEach { (key, value) in
|
|
value.frame = compartmentMap[key] ?? .zero
|
|
}
|
|
}
|
|
}
|