// // ZoomableScrollView.swift // SimpleX // // Created by Evgeny on 13/05/2022. // Copyright © 2022 SimpleX Chat. All rights reserved. // import SwiftUI struct ZoomableScrollView: UIViewRepresentable { private var content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } func makeUIView(context: Context) -> UIScrollView { // set up the UIScrollView let scrollView = UIScrollView() scrollView.delegate = context.coordinator // for viewForZooming(in:) scrollView.maximumZoomScale = 20 scrollView.minimumZoomScale = 1 scrollView.bouncesZoom = true scrollView.backgroundColor = .black scrollView.insetsLayoutMarginsFromSafeArea = false // create a UIHostingController to hold our SwiftUI content let hostedView = context.coordinator.hostingController.view! hostedView.translatesAutoresizingMaskIntoConstraints = true hostedView.autoresizingMask = [.flexibleWidth, .flexibleHeight] hostedView.frame = scrollView.bounds scrollView.addSubview(hostedView) return scrollView } func makeCoordinator() -> Coordinator { Coordinator(hostingController: UIHostingController(rootView: self.content)) } func updateUIView(_ uiView: UIScrollView, context: Context) { // update the hosting controller's SwiftUI content context.coordinator.hostingController.rootView = self.content assert(context.coordinator.hostingController.view.superview == uiView) } // MARK: - Coordinator class Coordinator: NSObject, UIScrollViewDelegate { var hostingController: UIHostingController init(hostingController: UIHostingController) { self.hostingController = hostingController } func viewForZooming(in scrollView: UIScrollView) -> UIView? { hostingController.view } } } struct ZoomablePageView: UIViewRepresentable { private var content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } func makeUIView(context: Context) -> UIScrollView { let scrollView = UIScrollView() scrollView.delegate = context.coordinator scrollView.maximumZoomScale = 5 scrollView.minimumZoomScale = 1 scrollView.bouncesZoom = true scrollView.backgroundColor = .clear let hostedView = context.coordinator.hostingController.view! hostedView.backgroundColor = .clear hostedView.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(hostedView) NSLayoutConstraint.activate([ hostedView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor), hostedView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor), hostedView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor), hostedView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor), hostedView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor) ]) return scrollView } func makeCoordinator() -> Coordinator { Coordinator(hostingController: UIHostingController(rootView: self.content)) } func updateUIView(_ uiView: UIScrollView, context: Context) { context.coordinator.hostingController.rootView = self.content } class Coordinator: NSObject, UIScrollViewDelegate { var hostingController: UIHostingController init(hostingController: UIHostingController) { self.hostingController = hostingController } func viewForZooming(in scrollView: UIScrollView) -> UIView? { hostingController.view } } }