Skip to content

Instantly share code, notes, and snippets.

@felginep
Created January 18, 2019 09:05
Show Gist options
  • Select an option

  • Save felginep/0148b40e26b19d07e81c2e1e4f2ff3d2 to your computer and use it in GitHub Desktop.

Select an option

Save felginep/0148b40e26b19d07e81c2e1e4f2ff3d2 to your computer and use it in GitHub Desktop.

Revisions

  1. felginep created this gist Jan 18, 2019.
    76 changes: 76 additions & 0 deletions ViewStyle.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,76 @@
    import Foundation
    import UIKit

    struct ViewStyle<T> {
    let style: (T) -> Void
    }

    let filled = ViewStyle<UIButton> {
    $0.setTitleColor(.white, for: .normal)
    $0.backgroundColor = .red
    }

    let rounded = ViewStyle<UIButton> {
    $0.layer.cornerRadius = 4.0
    }

    extension ViewStyle {

    func compose(with style: ViewStyle<T>) -> ViewStyle<T> {
    return ViewStyle<T> {
    self.style($0)
    style.style($0)
    }
    }
    }

    let roundedAndFilled = rounded.compose(with: filled)

    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 roundedAndFilled: ViewStyle<UIButton> {
    return rounded.compose(with: filled)
    }
    }

    func style<T>(_ object: T, with style: ViewStyle<T>) {
    style.style(object)
    }

    protocol Stylable {
    init()
    }

    extension UIView: Stylable {}

    extension Stylable {

    init(style: ViewStyle<Self>) {
    self.init()
    apply(style)
    }


    func apply(_ style: ViewStyle<Self>) {
    style.style(self)
    }
    }


    let button = UIButton(style: .roundedAndFilled)
    button.setTitle("My Button", for: .normal)
    button.sizeToFit()
    button