Skip to content

Instantly share code, notes, and snippets.

@svenmuennich
Forked from felginep/ViewStyle.swift
Created March 5, 2019 08:44
Show Gist options
  • Save svenmuennich/b4654cf852abdf3684ae96f1b09a8e52 to your computer and use it in GitHub Desktop.
Save svenmuennich/b4654cf852abdf3684ae96f1b09a8e52 to your computer and use it in GitHub Desktop.
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment