Skip to content

Instantly share code, notes, and snippets.

@ilyapuchka
Last active May 19, 2020 20:14
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilyapuchka/d363c7307233f33708e5eaf1a2b19ce2 to your computer and use it in GitHub Desktop.
Save ilyapuchka/d363c7307233f33708e5eaf1a2b19ce2 to your computer and use it in GitHub Desktop.
Adaptive Font styles
public protocol Stylish: class {
func updateStyle()
}
public class StyleProxy<S: Stylish>: NSObject {
fileprivate override init() { }
}
private class StyleProxyView<S: Stylish>: UIView {
var instance: S? { return superview as? S }
var style: StyleProxy<S> = StyleProxy()
override public func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
instance?.updateStyle()
}
}
extension Stylish where Self: UIView {
private(set) var style: StyleProxy<Self> {
get {
if let proxy = subviews.first(where: { $0 is StyleProxyView<Self> }) as? StyleProxyView<Self> {
return proxy.style
}
let proxy = StyleProxyView<Self>()
addSubview(proxy)
return proxy.style
}
set {
guard let proxy = subviews.first(where: { $0 is StyleProxyView<Self> }) as? StyleProxyView<Self> else { return }
styleView.style = newValue
updateStyle()
}
}
}
public typealias TextStyle = (UITraitCollection) -> UIFont?
private var _textStyleKey: Void?
public extension StyleProxy where S: UIButton {
var font: TextStyle? {
get {
return associatedValue(forKey: &_textStyleKey)
}
set {
retain(newValue, forKey: &_textStyleKey)
}
}
}
extension UIButton: Stylish {
public var textStyle: TextStyle? {
get { return style.font }
set { style.font = newValue }
}
public func updateStyle() {
self.titleLabel?.font = textStyle?(traitCollection) ?? titleLabel?.font
}
}
private var _textStyleKey: Void?
public extension StyleProxy where S: UILabel {
var font: TextStyle? {
get {
return associatedValue(forKey: &_textStyleKey)
}
set {
retain(newValue, forKey: &_textStyleKey)
}
}
}
extension UILabel: Stylish {
public var textStyle: TextStyle? {
get { return style.font }
set { style.font = newValue }
}
public func updateStyle() {
self.font = textStyle?(traitCollection) ?? font
invalidateIntrinsicContentSize()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment