Skip to content

Instantly share code, notes, and snippets.

@k-o-d-e-n
Last active November 23, 2022 09:43
Show Gist options
  • Save k-o-d-e-n/c959c2e86d28434e931bad64ee8601d4 to your computer and use it in GitHub Desktop.
Save k-o-d-e-n/c959c2e86d28434e931bad64ee8601d4 to your computer and use it in GitHub Desktop.
How to avoid an anonymous closure in lazy properties
/*
lazy var actionButton: UIButton = UIButton().add(to: view) { btn in
// button configuration
}
instead of:
lazy var actionButton: UIButton = {
let btn = UIButton()
addSubview(btn)
// button configuration
return btn
}()
*/
public protocol LazyLoadable {}
extension NSObject: LazyLoadable {}
public extension LazyLoadable {
func didLoad(_ completion: (Self) -> Void) -> Self {
completion(self); return self
}
/// Kotlin-like convenience accessor to instance
func `let`(_ closure: (Self) -> Void) -> Self {
closure(self); return self
}
}
#if canImport(QuartzCore)
import QuartzCore
public extension LazyLoadable where Self: CALayer {
func add(to superlayer: CALayer) -> Self {
superlayer.addSublayer(self); return self
}
func add(to superlayer: CALayer, completion: (Self) -> Void) -> Self {
superlayer.addSublayer(self); completion(self); return self
}
}
#endif
#if canImport(UIKit)
import UIKit
public extension LazyLoadable where Self: CALayer {
func insert(to superview: UIView, at index: UInt32) -> Self {
superview.layer.insertSublayer(self, at: index); return self
}
func insert(to superview: UIView, at index: UInt32, completion: (Self) -> Void) -> Self {
superview.layer.insertSublayer(self, at: index); completion(self); return self
}
func insert(to superview: UIView, above: CALayer, completion: (Self) -> Void) -> Self {
superview.layer.insertSublayer(self, above: above); completion(self); return self
}
func insert(to superview: UIView, below: CALayer, completion: (Self) -> Void) -> Self {
superview.layer.insertSublayer(self, below: below); completion(self); return self
}
func add(to superview: UIView) -> Self {
superview.layer.addSublayer(self); return self
}
func add(to superview: UIView, completion: (Self) -> Void) -> Self {
superview.layer.addSublayer(self); completion(self); return self
}
}
public extension LazyLoadable where Self: UIView {
func add(to superview: UIView) -> Self {
superview.addSubview(self); return self
}
func add(to superview: UIView, completion: (Self) -> Void) -> Self {
superview.addSubview(self); completion(self); return self
}
func insert(to superview: UIView, above: UIView, completion: (Self) -> Void) -> Self {
superview.insertSubview(self, aboveSubview: above); completion(self); return self
}
func insert(to superview: UIView, below: UIView, completion: (Self) -> Void) -> Self {
superview.insertSubview(self, belowSubview: below); completion(self); return self
}
func add(to superview: UIView?) -> Self {
superview?.addSubview(self); return self
}
func add(to superview: UIView?, completion: (Self) -> Void) -> Self {
superview?.addSubview(self); completion(self); return self
}
func insert(to superview: UIView?, above: UIView, completion: (Self) -> Void) -> Self {
superview?.insertSubview(self, aboveSubview: above); completion(self); return self
}
func insert(to superview: UIView?, below: UIView, completion: (Self) -> Void) -> Self {
superview?.insertSubview(self, belowSubview: below); completion(self); return self
}
func insert(to superview: UIView?, at index: Int, completion: (Self) -> Void) -> Self {
superview?.insertSubview(self, at: index); completion(self); return self
}
}
public extension LazyLoadable where Self: UILayoutGuide {
func add(to superview: UIView) -> Self {
superview.addLayoutGuide(self); return self
}
func add(to superview: UIView, completion: (Self) -> Void) -> Self {
completion(add(to: superview)); return self
}
}
public extension LazyLoadable where Self: UIViewController {
func add(to superController: UIViewController) -> Self {
superController.add(child: self)
return self
}
func add(to superController: UIViewController, completion: (Self) -> Void) -> Self {
completion(add(to: superController)); return self
}
}
#endif
#if os(macOS)
import AppKit
public extension LazyLoadable where Self: CALayer {
func insert(to superview: NSView, at index: UInt32) -> Self {
superview.layer?.insertSublayer(self, at: index); return self
}
func insert(to superview: NSView, at index: UInt32, completion: (Self) -> Void) -> Self {
superview.layer?.insertSublayer(self, at: index); completion(self); return self
}
func insert(to superview: NSView, above: CALayer, completion: (Self) -> Void) -> Self {
superview.layer?.insertSublayer(self, above: above); completion(self); return self
}
func insert(to superview: NSView, below: CALayer, completion: (Self) -> Void) -> Self {
superview.layer?.insertSublayer(self, below: below); completion(self); return self
}
func add(to superview: NSView) -> Self {
superview.layer?.addSublayer(self); return self
}
func add(to superview: NSView, completion: (Self) -> Void) -> Self {
superview.layer?.addSublayer(self); completion(self); return self
}
}
public protocol _SubviewsContainer {
var __contentView: NSView { get }
}
extension NSView: _SubviewsContainer {
public var __contentView: NSView { self }
}
extension NSViewController: _SubviewsContainer {
public var __contentView: NSView { view }
}
public extension LazyLoadable where Self: NSView {
func add<C>(to superview: C) -> Self where C: _SubviewsContainer {
superview.__contentView.addSubview(self); return self
}
func add<C>(to superview: C, completion: (Self) -> Void) -> Self where C: _SubviewsContainer {
superview.__contentView.addSubview(self); completion(self); return self
}
func insert<C>(to superview: C, above: NSView, completion: (Self) -> Void) -> Self where C: _SubviewsContainer {
superview.__contentView.addSubview(self, positioned: .above, relativeTo: above); completion(self); return self
}
func insert<C>(to superview: C, below: NSView, completion: (Self) -> Void) -> Self where C: _SubviewsContainer {
superview.__contentView.addSubview(self, positioned: .below, relativeTo: below); completion(self); return self
}
func add<C>(to superview: C?) -> Self where C: _SubviewsContainer {
superview?.__contentView.addSubview(self); return self
}
func add<C>(to superview: C?, completion: (Self) -> Void) -> Self where C: _SubviewsContainer {
superview?.__contentView.addSubview(self); completion(self); return self
}
func insert<C>(to superview: C?, above: NSView, completion: (Self) -> Void) -> Self where C: _SubviewsContainer {
superview?.__contentView.addSubview(self, positioned: .above, relativeTo: above); completion(self); return self
}
func insert<C>(to superview: C?, below: NSView, completion: (Self) -> Void) -> Self where C: _SubviewsContainer {
superview?.__contentView.addSubview(self, positioned: .below, relativeTo: below); completion(self); return self
}
func insert<C>(to superview: C?, at index: Int, completion: (Self) -> Void) -> Self where C: _SubviewsContainer {
guard let sView = superview?.__contentView else { completion(self); return self }
if sView.subviews.count > index {
sView.addSubview(self, positioned: .below, relativeTo: sView.subviews[index])
} else {
sView.addSubview(self)
}
completion(self)
return self
}
}
@available(macOS 10.11, *)
public extension LazyLoadable where Self: NSLayoutGuide {
func add(to superview: NSView) -> Self {
superview.addLayoutGuide(self); return self
}
func add(to superview: NSView, completion: (Self) -> Void) -> Self {
completion(add(to: superview)); return self
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment