Created
January 18, 2019 09:05
-
-
Save felginep/0148b40e26b19d07e81c2e1e4f2ff3d2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
I like the idea of overloading the +
operator
extension ViewStyle {
static func +(left: ViewStyle<T>, right: ViewStyle<T>) -> ViewStyle<T> {
return ViewStyle<T> {
left.style($0)
right.style($0)
return $0
}
}
}
So then you can do
let button = UIButton(style: rounded + filled)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How could you allow composing ViewStyles for UIView subclasses with ViewStyles for UIView?