Created
March 17, 2024 23:57
-
-
Save StewartLynch/af580eeb00e2247df474b389b4c48416 to your computer and use it in GitHub Desktop.
A Zoomable and Scrollable Image View for SwiftUI
This file contains 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
// | |
// Created for SwiftData Photo_Camera | |
// by Stewart Lynch on 2024-02-18 | |
// | |
// Follow me on Mastodon: @[email protected] | |
// Follow me on Threads: @StewartLynch (https://www.threads.net) | |
// Follow me on X: https://x.com/StewartLynch | |
// Follow me on LinkedIn: https://linkedin.com/in/StewartLynch | |
// Subscribe on YouTube: https://youTube.com/@StewartLynch | |
// Buy me a ko-fi: https://ko-fi.com/StewartLynch | |
import SwiftUI | |
struct ZoomableScrollView<Content: View>: 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 | |
// 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 { | |
return Coordinator(hostingController: UIHostingController(rootView: self.content)) | |
} | |
func updateUIView(_ uiView: UIScrollView, context: Context) { | |
// update the hosting controller's SwiftUI content | |
uiView.setZoomScale(1.0, animated: true) | |
context.coordinator.hostingController.rootView = self.content | |
assert(context.coordinator.hostingController.view.superview == uiView) | |
} | |
// Coordinator | |
class Coordinator: NSObject, UIScrollViewDelegate { | |
var hostingController: UIHostingController<Content> | |
init(hostingController: UIHostingController<Content>) { | |
self.hostingController = hostingController | |
} | |
func viewForZooming(in scrollView: UIScrollView) -> UIView? { | |
return hostingController.view | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment