popeyelau / wiki

📒Wiki for many useful notes, source, commands and snippets.
3 stars 0 forks source link

ViewStyle #21

Open popeyelau opened 5 years ago

popeyelau commented 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