Last active
January 12, 2020 18:06
-
-
Save alexdrone/195c35032539fed31c9ecb469bac3d3b to your computer and use it in GitHub Desktop.
(UIKit >> SwiftUI) Inline bridge view using some @dynamicMemberLookup magic.
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
import Foundation | |
import UIKit | |
import SwiftUI | |
// MARK: - UIViewBridge | |
/// Usage: | |
/// | |
/// var body: some View { | |
/// ... | |
/// UIViewBridge<UILabel> { view, context in | |
/// view.backgroundColor = UIColor.red | |
/// view.text = "Hello" | |
/// } | |
/// ... | |
public struct UIViewBridge<T: UIView>: UIViewRepresentable { | |
public typealias Coordinator = UIViewBridgeCoordinator<T> | |
public typealias Context = UIViewRepresentableContext<UIViewBridge<T>> | |
/// Reference to the concrete `UIView` instance. | |
public let view: T | |
/// The `UIViewRepresentable` coordinator object. | |
/// - note: Pass a custom coordinator by subclassing `UIViewBridgeCoordinator<T>` and pass an | |
/// instance of it to `createCoordinatorClosure` | |
public var coordinator: UIViewBridgeCoordinator<T>? | |
/// View configuration closure. | |
private let _configureClosure: (T, Context) -> Void | |
init( | |
createInstanceClosure: () -> T = { T() }, | |
createCoordinatorClosure: (Self) -> Coordinator = { Coordinator(bridge: $0) }, | |
configureClosure: @escaping (T, Context) -> Void | |
) { | |
self.view = createInstanceClosure() | |
self._configureClosure = configureClosure | |
self.coordinator = createCoordinatorClosure(self) | |
} | |
/// MARK: - UIViewRepresentable | |
public func makeUIView(context: Context) -> T { | |
view | |
} | |
public func updateUIView(_ uiView: T, context: Context) { | |
_configureClosure(uiView, context) | |
self.coordinator?.bridge = self | |
} | |
public func makeCoordinator() -> UIViewBridgeCoordinator<T> { | |
coordinator! | |
} | |
} | |
// MARK: - UIViewBridgeCoordinator | |
open class UIViewBridgeCoordinator<T: UIView>: NSObject { | |
/// A copy of the view wrapped (updated at the latest `updateUIView(_:context)`). | |
public var bridge: UIViewBridge<T> | |
public init(bridge: UIViewBridge<T>) { | |
self.bridge = bridge | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment