Skip to content

Instantly share code, notes, and snippets.

@uchcode
Created March 28, 2020 15:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uchcode/50a9a049ea79b685b4b9542effe670d7 to your computer and use it in GitHub Desktop.
Save uchcode/50a9a049ea79b685b4b9542effe670d7 to your computer and use it in GitHub Desktop.
SwiftUI with UIViewController Design Pattern.
import SwiftUI
import SafariServices
struct DemoView: View, Hostable {
@EnvironmentObject var hostedObject: HostingObject<DemoView>
var address: String = "https://example.com"
func present() { // UIKit code
let safari = SFSafariViewController(url: URL(string: address)!)
hostedObject.viewController?.present(safari, animated: true)
}
var body: some View {
Button(address, action: present)
}
}
struct ContentView: View {
var body: some View {
DemoView().hosting()
}
}
///=======
protocol Hostable: View {
associatedtype Content: View
var hostedObject: HostingObject<Self> { get }
func hosting() -> Content
}
extension Hostable {
func hosting() -> some View {
HostingObjectView(rootView: self)
}
}
class HostingObject<ViewType: View>: ObservableObject {
@Published var viewController: UIViewController? = nil
}
struct HostingObjectView<Content: View>: View {
var rootView: Content
var hostedObject = HostingObject<Content>()
func getHost(viewController: UIViewController) {
hostedObject.viewController = viewController.parent
}
var body: some View {
Group {
rootView
}
.uiViewController(didAppear: getHost(viewController:))
.environmentObject(hostedObject)
}
}
extension View {
func uiViewController(didAppear: @escaping (UIViewController) -> ()) -> some View {
modifier(UIViewControllerViewModifier(didAppear:didAppear))
}
}
struct UIViewControllerViewModifier: ViewModifier {
var didAppear: (UIViewController) -> Void
func body(content: Content) -> some View {
content.background( UIViewControllerView(didAppear: didAppear) )
}
}
struct UIViewControllerView: UIViewControllerRepresentable {
final class ViewController: UIViewController {
var didAppear: (UIViewController) -> Void = { _ in }
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
didAppear(self)
}
}
var didAppear: (UIViewController) -> Void
func makeUIViewController(context: Context) -> UIViewController {
let viewController = ViewController()
viewController.didAppear = didAppear
return viewController
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
//
}
}
import PlaygroundSupport
PlaygroundPage.current.setLiveView(ContentView())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment