Last active
February 13, 2020 12:17
-
-
Save MaximKotliar/dff0b195e910196270125869a3ad5b0e 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
// | |
// KeyPathBasedConfiguration.swift | |
// | |
// Created by Maxim Kotliar on 13.02.2020. | |
// Copyright © 2020 Wikrgroup. All rights reserved. | |
// | |
import Foundation | |
@dynamicMemberLookup | |
struct KeyPathBasedConfiguration<Base: AnyObject> { | |
struct KeyPathConfig { | |
fileprivate let keyPath: PartialKeyPath<Base> | |
fileprivate let value: Any | |
fileprivate let apply: ((Base) -> Void) | |
init<T>(_ keyPath: ReferenceWritableKeyPath<Base, T>, _ value: T) { | |
self.keyPath = keyPath | |
self.value = value | |
self.apply = { $0[keyPath: keyPath] = value } | |
} | |
} | |
init(_ keyPathConfigurations: [KeyPathConfig]) { | |
var configs: [AnyKeyPath: KeyPathConfig] = [:] | |
for config in keyPathConfigurations { | |
configs[config.keyPath] = config | |
} | |
self.configurations = configs | |
} | |
private var configurations: [AnyKeyPath: KeyPathConfig] | |
subscript <T>(dynamicMember keyPath: ReferenceWritableKeyPath<Base, T>) -> T? { | |
get { | |
configurations[keyPath]?.value as? T | |
} | |
set { | |
guard let newValue = newValue else { | |
configurations[keyPath] = nil | |
return | |
} | |
configurations[keyPath] = .init(keyPath, newValue) | |
} | |
} | |
func apply(to base: Base, ignoring: Set<PartialKeyPath<Base>>) { | |
for (_, config) in configurations { | |
guard !ignoring.contains(config.keyPath) else { continue } | |
config.apply(base) | |
} | |
} | |
} | |
// Example | |
import UIKit | |
extension UINavigationItem { | |
typealias NavigationBarConfiguration = KeyPathBasedConfiguration<UINavigationBar> | |
} | |
extension UINavigationItem.NavigationBarConfiguration { | |
static let `default` = UINavigationItem.NavigationBarConfiguration([.init(\.isHidden, false), | |
.init(\.isTranslucent, true), | |
.init(\.backgroundColor, .clear), | |
.init(\.tintColor, .white)]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment