1

使用 Swift5.3.2、iOS14.4.1、Xcode12.4、

我正在尝试.simultaneousGesture在 SwiftUI 中使用修饰符。

据我了解,此修饰符应确保手势(例如点击、长按、放大等)应该能够在视图中共存。

在我的示例中,我使用的是 ZoomableScrollView。只要我不使用simultaneousGesture.

但是,一旦我使用了额外的同步手势,ZoomableScrollView 就不再是“可缩放的”(即,它的手势都不再起作用了)。

我该怎么做才能使缩放仍然有效并获得额外的 dragGesture ?

import SwiftUI

struct MediaTabView: View {
    
    @GestureState private var dragOffset: CGFloat = -100
    
    var body: some View {

        ZoomableScrollView {
            Image(uiImage: UIImage(contentsOfFile: url.path)!)
                .resizable()
                .scaledToFit()
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.black)
        .simultaneousGesture(
            DragGesture()
                .updating($dragOffset) { (value, gestureState, transaction) in
                    let delta = value.location.x - value.startLocation.x
                    if delta > 10 { // << some appropriate horizontal threshold here
                        gestureState = delta
                        print(delta)
                    }
                }
                .onEnded {
                    if $0.translation.width > 100 {
                        // Go to the previous slide
                        print("on ended")
                    }
                }
        )        
    }
}

ZoomableScrollView 的代码在这里:

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
    hostedView.backgroundColor = .black
    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<Content>

    init(hostingController: UIHostingController<Content>) {
      self.hostingController = hostingController
    }

    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
      return hostingController.view
    }
  }
}
4

0 回答 0