Open popeyelau opened 5 years ago
import UIKit import PlaygroundSupport protocol Stylable { init() } extension Stylable { init(style: ViewStyle<Self>) { self.init() apply(style) } func apply(_ style: ViewStyle<Self>) -> Self { style.style(self) return self } } struct ViewStyle<T> { let style: (T) -> Void static func +(lhs: ViewStyle<T>, rhs: ViewStyle<T>) -> ViewStyle<T> { return ViewStyle<T> { lhs.style($0) rhs.style($0) } } } extension UIView: Stylable {} extension ViewStyle where T: UIButton { static var filled: ViewStyle<UIButton> { return ViewStyle<UIButton> { $0.setTitleColor(.white, for: .normal) $0.backgroundColor = .red } } static var rounded: ViewStyle<UIButton> { return ViewStyle<UIButton> { $0.layer.cornerRadius = 4.0 } } static var subtitle: ViewStyle<UIButton> { return ViewStyle<UIButton> { $0.titleLabel?.font = .systemFont(ofSize: 12) $0.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8) } } static var roundedAndFilled: ViewStyle<UIButton> { return rounded + filled } static func title(_ title: String?, for state: UIControl.State) -> ViewStyle<UIButton> { return ViewStyle<UIButton> { $0.setTitle(title, for: state) $0.sizeToFit() } } } // Use let button = UIButton(style: .roundedAndFilled) .apply(.subtitle) .apply(.title("Hello World", for: .normal)) PlaygroundPage.current.liveView = button