Skip to content

Instantly share code, notes, and snippets.

@PimCoumans
Last active November 19, 2020 10:50
Show Gist options
  • Save PimCoumans/0c73708649d003e867049fdbe12c6ea7 to your computer and use it in GitHub Desktop.
Save PimCoumans/0c73708649d003e867049fdbe12c6ea7 to your computer and use it in GitHub Desktop.
Allows classes to be configured and initialized with a closure
import UIKit
/// Adds a `configure` method with a closure that is executed with `Self` as a parameter
protocol Configurable { }
extension Configurable {
/// Configures the instance with a closure that is executed with `Self` as a parameter
/// - Parameter configurer: Closure exectured immediately with `Self` as a parameter
/// - Parameter instance: Use this parameter to 'configure' the instance
func configure(with configurer: (_ instance: Self) -> Void) {
configurer(self)
}
}
/// Allows the type to be initialized with a configuration closure, requiring it to at least have an `init()` method
protocol InitConfigurable: Configurable {
init()
}
extension InitConfigurable {
/// Initailizes the type with a closure that is executed with `Self` as a parameter
/// - Parameter configurer: Closure called immidiately after initialization. Use it to configure the instance
/// - Parameter instance: Use this parameter to 'configure' the instance
///
/// Using this method allows classes to be instantiated like in the following example
/// ```
/// let view = UIView { view in
/// view.backgroundColor = .white
/// view.layer.cornerRadius = 16
/// view.layer.masksToBounds = true
/// view.layer.cornerCurve = .continuous
/// }
init(with configurer: (_ instance: Self) -> Void) {
self.init()
configure(with: configurer)
}
}
/// Behavior added to all subclasses of NSObject, but might not work in all projects
/// Could also be added to `UIView` instead
extension NSObject: InitConfigurable { }
/// Special case for `UITableView` that can initialize with a style too
extension UITableView {
public convenience init(style: UITableView.Style, configurer: (_ instance: Self) -> Void) {
self.init(frame: .zero, style: style)
configurer(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment