可拖动和可缩放的AsyncImage不会触发长按手势

问题描述 投票:0回答:1

我有一个

AsyncImage
,可以通过
MagnifyGesture
进行缩放,并可以通过视图修改器进行绘制。绘图和缩放按预期工作。但现在我想通过
onLongPressGesture
显示叠加层,但这不会触发。如果我删除
.draggable
它就可以了。我该如何解决它?

public struct ContentView: View {
    
    @ObservedObject private var viewState: ViewState
    @State private var showAltText: Bool = false
    @State private var currentZoom = 0.0
    @State private var totalZoom   = 1.0
    
    public init(viewState vs:ViewState) {
        viewState = vs
    }
    public var body: some View {
        ZStack {
            VStack {
                if viewState.selectedComicStrip != nil {
                    AsyncImage(url: viewState.selectedComicStrip!.imageURL) { image in
                        image.resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(maxWidth: 400, maxHeight: 600)
                    } placeholder: {
                        Text("placeholder").frame(maxWidth: 400, maxHeight: 600)
                    }
                    .draggable()
                    .scaleEffect(currentZoom + totalZoom)
                    .gesture(
                        MagnifyGesture()
                            .onChanged { value in
                                currentZoom = value.magnification - 1
                            }
                            .onEnded { value in
                                totalZoom += currentZoom
                                currentZoom = 0
                            }
                    )
                    .onLongPressGesture {
                        showAltText.toggle()
                        DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
                            showAltText = false
                        }
                    }
                } else {
                    Text("placeholder")
                }
            }
        }.fullScreenCover(isPresented: $showAltText, content: {
            ZStack {
                Color.black.opacity(0.8)
                    .edgesIgnoringSafeArea(.all)
                Text(viewState.selectedComicStrip!.altText)
                    .foregroundStyle(.white)
                    .padding()
            }
        })
        .padding()
    }
}

//https://stackoverflow.com/a/63082240/106435
struct DraggableView: ViewModifier {
    @State var offset = CGPoint(x: 0, y: 0)
    
    func body(content: Content) -> some View {
        content
            .gesture(DragGesture(minimumDistance: 0)
                .onChanged { value in
                    self.offset.x += value.location.x - value.startLocation.x
                    self.offset.y += value.location.y - value.startLocation.y
                })
            .offset(x: offset.x, y: offset.y)
    }
}

extension View {
    func draggable() -> some View {
        return modifier(DraggableView())
    }
}
swift swiftui gesture-recognition
1个回答
1
投票

根据 this Hacking with Swift 帖子和其他一些帖子,SwiftUI 默认情况下一次只会触发一个手势。 然而,据我从文档中可以看出,确切的行为通常是未定义的:

当您向应用程序的视图层次结构添加多个手势时,您需要决定手势如何相互交互。您可以使用手势组合来定义 SwiftUI 识别手势的顺序。 [SwiftUI 文档,重点是我的。]

受到this所以问题的启发,你可以尝试一些事情:

  1. 将长按手势包含在
    simultaneousGesture
    修饰符中。 (文档建议的可能是最强大的方法。)
  2. minimumDistance
    上设置正
    DragGesture
    。 (这样,它不会立即触发并阻止长按手势触发。)
  3. onLongPressGesture
    之前添加
    DragGesture
    。 (可能是最脆弱的选择。)
© www.soinside.com 2019 - 2024. All rights reserved.