Isn't there an easy way to pinch to zoom in an image in Swiftui?

前端 未结 7 1497
自闭症患者
自闭症患者 2020-12-28 08:07

I want to be able to resize and move an image in SwiftUI (like if it were a map) with pinch to zoom and drag it around.

With UIKit I embedded the image into a

7条回答
  •  伪装坚强ぢ
    2020-12-28 08:49

    The other answers here are overly complicated with custom zooming logic. If you want the standard, battle-tested UIScrollView zooming behavior you can just use a UIScrollView!

    SwiftUI allows you to put any UIView inside an otherwise SwiftUI view hierarchy using UIViewRepresentable or UIViewControllerRepresentable. Then to put more SwiftUI content inside that view, you can use UIHostingController. Read more about SwiftUI–UIKit interop in Interfacing with UIKit and the API docs.

    You can find a more complete example where I'm using this in a real app at: https://github.com/jtbandes/SpacePOD/blob/main/SpacePOD/ZoomableScrollView.swift (That example also includes more tricks for centering the image.)

    var body: some View {
      ZoomableScrollView {
        Image("Your image here")
      }
    }
    
    
    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
    
        // 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
        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? {
          return hostingController.view
        }
      }
    }
    

提交回复
热议问题