Created
October 22, 2019 07:27
-
-
Save kaizeiyimi/17b13c7263b7069e538099a99f5efbe7 to your computer and use it in GitHub Desktop.
SwiftUI+UIKit Preview
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 SwiftUI | |
import UIKit | |
@available(iOS 13, *) | |
public enum UIKitRepresentable { | |
public static func view<V, Model>( | |
viewType: V.Type = V.self, model: Model, | |
make: @escaping ((context: UIViewRepresentableContext<_UIKitView<V,Model, Void>>, model: Model)) -> V, | |
update: (((uiView: V, context: UIViewRepresentableContext<_UIKitView<V,Model, Void>>, model: Model)) -> Void)? = nil, | |
dismantle: (((uiView: V, coordinator: Void)) -> Void)? = nil) -> _UIKitView<V, Model, Void> { | |
return _UIKitView(viewType: viewType, model: model, coordinator: {}, | |
make: make, update: update, dismantle: dismantle) | |
} | |
public static func view<V, Model, COO>( | |
viewType: V.Type = V.self, model: Model, | |
coordinator: @escaping () -> COO, | |
make: @escaping ((context: UIViewRepresentableContext<_UIKitView<V,Model, COO>>, model: Model)) -> V, | |
update: (((uiView: V, context: UIViewRepresentableContext<_UIKitView<V,Model, COO>>, model: Model)) -> Void)? = nil, | |
dismantle: (((uiView: V, coordinator: COO)) -> Void)? = nil) -> _UIKitView<V, Model, COO> { | |
return _UIKitView(viewType: viewType, model: model, coordinator: coordinator, | |
make: make, update: update, dismantle: dismantle) | |
} | |
public static func viewController<VC, Model>( | |
vcType: VC.Type = VC.self, model: Model, | |
make: @escaping ((context: UIViewControllerRepresentableContext<_UIKitViewController<VC, Model, Void>>, model: Model)) -> VC, | |
update: (((uiViewController: VC, context: UIViewControllerRepresentableContext<_UIKitViewController<VC, Model, Void>>, model: Model)) -> Void)? = nil, | |
dismantle: (((uiViewController: VC, coordinator: Void)) -> Void)? = nil) -> _UIKitViewController<VC, Model, Void> { | |
return _UIKitViewController(vcType: vcType, model: model, coordinator: {}, | |
make: make, update: update, dismantle: dismantle) | |
} | |
public static func viewController<VC, Model, COO>( | |
vcType: VC.Type = VC.self, model: Model, | |
coordinator: @escaping () -> COO, | |
make: @escaping ((context: UIViewControllerRepresentableContext<_UIKitViewController<VC, Model, COO>>, model: Model)) -> VC, | |
update: (((uiViewController: VC, context: UIViewControllerRepresentableContext<_UIKitViewController<VC, Model, COO>>, model: Model)) -> Void)? = nil, | |
dismantle: (((uiViewController: VC, coordinator: COO)) -> Void)? = nil) -> _UIKitViewController<VC, Model, COO> { | |
return _UIKitViewController(vcType: vcType, model: model, coordinator: coordinator, | |
make: make, update: update, dismantle: dismantle) | |
} | |
private static var associationKey = "FunctionWrapper.dismantle.association.key" | |
private final class DismantleWrapper<V, COO>: NSObject { | |
let exec: (V, COO) -> Void | |
init(_ exec: @escaping (V, COO) -> Void) { | |
self.exec = exec | |
super.init() | |
} | |
} | |
} | |
// MARK: - UIView | |
@available(iOS 13, *) | |
extension UIKitRepresentable { | |
public struct _UIKitView<V: UIView, Model, COO>: UIViewRepresentable { | |
private let model: Model | |
private let coordinator: () -> COO | |
private let make: ((context: Context, model: Model)) -> V | |
private let update: (((uiView: V, context: Context, model: Model)) -> Void)? | |
private let dismantle: (((uiView: V, coordinator: COO)) -> Void)? | |
fileprivate init(viewType: V.Type = V.self, model: Model, | |
coordinator: @escaping () -> COO, | |
make: @escaping ((context: Context, model: Model)) -> V, | |
update: (((uiView: V, context: Context, model: Model)) -> Void)? = nil, | |
dismantle: (((uiView: V, coordinator: COO)) -> Void)? = nil) { | |
self.model = model | |
self.coordinator = coordinator | |
self.make = make | |
self.update = update | |
self.dismantle = dismantle | |
} | |
public func makeCoordinator() -> COO { | |
return coordinator() | |
} | |
public func makeUIView(context: Context) -> V { | |
let view = make((context, model)) | |
if let dismantle = dismantle { | |
let wrapper = DismantleWrapper<V, COO>{ dismantle(($0, $1)) } | |
objc_setAssociatedObject(view, &associationKey, wrapper, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) | |
} | |
return view | |
} | |
public func updateUIView(_ uiView: V, context: Context) { | |
update?((uiView, context, model)) | |
} | |
public static func dismantleUIView(_ uiView: V, coordinator: COO) { | |
if let wrapper = objc_getAssociatedObject(uiView, &associationKey) as? DismantleWrapper<V, COO> { | |
wrapper.exec(uiView, coordinator) | |
} | |
} | |
} | |
} | |
// MARK: - UIViewController | |
@available(iOS 13, *) | |
extension UIKitRepresentable { | |
public struct _UIKitViewController<VC: UIViewController, Model, COO>: UIViewControllerRepresentable { | |
private let model: Model | |
private let coordinator: () -> COO | |
private let make: ((context: Context, model: Model)) -> VC | |
private let update: (((uiViewController: VC, context: Context, model: Model)) -> Void)? | |
private let dismantle: (((uiViewController: VC, coordinator: COO)) -> Void)? | |
fileprivate init(vcType: VC.Type = VC.self, model: Model, | |
coordinator: @escaping () -> COO, | |
make: @escaping ((context: Context, model: Model)) -> VC, | |
update: (((uiViewController: VC, context: Context, model: Model)) -> Void)? = nil, | |
dismantle: (((uiViewController: VC, coordinator: COO)) -> Void)? = nil) { | |
self.model = model | |
self.coordinator = coordinator | |
self.make = make | |
self.update = update | |
self.dismantle = dismantle | |
} | |
public func makeCoordinator() -> COO { | |
return coordinator() | |
} | |
public func makeUIViewController(context: Context) -> VC { | |
let vc = make((context, model)) | |
if let dismantle = dismantle { | |
let wrapper = DismantleWrapper<VC, COO>{ dismantle(($0, $1)) } | |
objc_setAssociatedObject(vc, &associationKey, wrapper, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) | |
} | |
return vc | |
} | |
public func updateUIViewController(_ uiViewController: VC, context: Context) { | |
update?((uiViewController, context, model)) | |
} | |
public static func dismantleUIViewController(_ uiViewController: VC, coordinator: COO) { | |
if let wrapper = objc_getAssociatedObject(uiViewController, &associationKey) as? DismantleWrapper<VC, COO> { | |
wrapper.exec(uiViewController, coordinator) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@kaizeiyimi Hi! Very interested in your code. Can you tell me how to use it?