我有一个
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())
}
}
根据 this Hacking with Swift 帖子和其他一些帖子,SwiftUI 默认情况下一次只会触发一个手势。 然而,据我从文档中可以看出,确切的行为通常是未定义的:
当您向应用程序的视图层次结构添加多个手势时,您需要决定手势如何相互交互。您可以使用手势组合来定义 SwiftUI 识别手势的顺序。 [SwiftUI 文档,重点是我的。]
受到this所以问题的启发,你可以尝试一些事情:
simultaneousGesture
修饰符中。 (文档建议的可能是最强大的方法。)minimumDistance
上设置正 DragGesture
。 (这样,它不会立即触发并阻止长按手势触发。)onLongPressGesture
之前添加 DragGesture
。 (可能是最脆弱的选择。)