Skip to content

Instantly share code, notes, and snippets.

@andreyz
Last active February 17, 2018 21:59
Show Gist options
  • Save andreyz/a6970057fb22dd211083c17fc571de2f to your computer and use it in GitHub Desktop.
Save andreyz/a6970057fb22dd211083c17fc571de2f to your computer and use it in GitHub Desktop.
Initialisers through key paths
public extension UIEdgeInsets {
public var vertical: CGFloat {
get { return 0 } // meaningless but not fatal
set { (top, bottom) = (newValue, newValue) }
}
public var horizontal: CGFloat {
get { return 0 } // meaningless but not fatal
set { (left, right) = (newValue, newValue) }
}
public var all: CGFloat {
get { return 0 } // meaningless but not fatal
set { (vertical, horizontal) = (newValue, newValue) }
}
}
extension UIEdgeInsets: UniformKeypathInitializable {
public typealias Value = CGFloat
}
let insets: UIEdgeInsets = [\.left: 8]
print(insets) // (l: 8.0, r: 0.0, t: 0.0, b: 0.0)
/// Allows dictionary literal initialization for any
/// conforming type that declares `typealias Value`,
/// where `Value` refers to a uniform property Type
/// that can be set through a keypath-value dictionary
///
/// - Example:
/// ```
/// extension CGPoint : UniformKeypathInitializable {
/// public typealias Value = CGFloat
/// }
///
/// let p: CGPoint = [\.x: 0, \.y: 20]
/// ```
public protocol UniformKeypathInitializable : ExpressibleByDictionaryLiteral {
/// Allow zero-argument initializer
init()
}
extension UniformKeypathInitializable {
/// Initializes each member of a keypath-value
/// dictionary, allowing the type to be initialized
/// with a dictionary literal
public init(dictionaryLiteral elements: (WritableKeyPath<Self, Value>, Value)...) {
self.init()
for (property, value) in elements {
self[keyPath: property] = value
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment