Last active
November 23, 2022 09:43
-
-
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
This file contains hidden or 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
/* | |
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