Created
November 20, 2019 16:30
-
-
Save DanielCardonaRojas/270fa90e905b096216131aa27a388685 to your computer and use it in GitHub Desktop.
A small DSL to group and compose styles for UIKit components.
This file contains hidden or 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
// | |
// Style.swift | |
// ComposableStyles | |
// | |
// Created by Daniel Cardona Rojas on 20/11/19. | |
// Copyright © 2019 Daniel Cardona Rojas. All rights reserved. | |
// | |
import UIKit | |
struct GenericStyle { | |
private let styling: (UIView) -> Void | |
init(_ styling: @escaping (UIView) -> Void) { | |
self.styling = styling | |
} | |
func apply(to view: UIView) { | |
styling(view) | |
} | |
} | |
struct Style<T: UIView> { | |
private let styling: (T) -> Void | |
init(_ styling: @escaping (T) -> Void) { | |
self.styling = styling | |
} | |
func apply(to view: T) { | |
styling(view) | |
} | |
} | |
// MARK: Shorthand helpers | |
extension Style { | |
static func property<P>(_ keyPath: ReferenceWritableKeyPath<T,P>, value: P) -> Style { | |
return Style { v in | |
v[keyPath: keyPath] = value | |
} | |
} | |
static func adjustingProperty<P>(_ keyPath: ReferenceWritableKeyPath<T,P>) -> (P) -> Style { | |
return { (value: P) in | |
Style { v in v[keyPath: keyPath] = value } | |
} | |
} | |
} | |
extension GenericStyle { | |
static func property<P>(_ keyPath: ReferenceWritableKeyPath<UIView,P>, value: P) -> GenericStyle { | |
return GenericStyle { v in | |
v[keyPath: keyPath] = value | |
} | |
} | |
static func adjustingProperty<P>(_ keyPath: ReferenceWritableKeyPath<UIView,P>) -> (P) -> GenericStyle { | |
return { (value: P) in | |
GenericStyle { v in v[keyPath: keyPath] = value } | |
} | |
} | |
} | |
// MARK: Combining styles | |
func +<V>(_ lhs: Style<V>, rhs: Style<V>) -> Style<V> { | |
return Style { (v: V) -> Void in | |
lhs.apply(to: v) | |
rhs.apply(to: v) | |
} | |
} | |
func +<V>(_ lhs: Style<V>, rhs: GenericStyle) -> Style<V> { | |
return Style { (v: V) -> Void in | |
lhs.apply(to: v) | |
rhs.apply(to: v) | |
} | |
} | |
func +<V>(_ lhs: GenericStyle, rhs: Style<V>) -> Style<V> { | |
return Style { (v: V) -> Void in | |
lhs.apply(to: v) | |
rhs.apply(to: v) | |
} | |
} | |
func +(_ lhs: GenericStyle, rhs: GenericStyle) -> GenericStyle { | |
return GenericStyle { (v: UIView) -> Void in | |
lhs.apply(to: v) | |
rhs.apply(to: v) | |
} | |
} | |
// MARK: Component Specific helpers | |
extension UIView { | |
func applying(_ style: GenericStyle) { | |
style.apply(to: self) | |
} | |
} | |
extension UILabel { | |
func applying(_ style: Style<UILabel>) { | |
style.apply(to: self) | |
} | |
} | |
extension UIButton { | |
func applying(_ style: Style<UIButton>) { | |
style.apply(to: self) | |
} | |
} | |
extension UICollectionViewCell { | |
func applying(_ style: Style<UICollectionViewCell>) { | |
style.apply(to: self) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment