问题描述
我创建了一个包含主视图的应用程序,其中有多个视图,每个形状一个。对于形状,我想启用一些交互以便在点击时变换其属性。由于转换也取决于抽头位置,因此我已通过以下方式将其实现为DragGesture:
.gesture(DragGesture(minimumdistance: 0,coordinateSpace: .global)
.onChanged { gesture in
print("Tap location: \(gesture.startLocation)")
})
除了单个形状的转换外,我还希望用户能够拖动整个内容和/或调整其大小。因此,在主视图中,我实现了拖动手势和放大手势。由于点击和拖动存在冲突,因此我添加了一个选项来在点击和拖动之间切换交互模式。通过检查形状视图中的以下条件来启用/禁用转换:
.allowsHitTesting(dragGestureMode == DragGestureEnum.TransformShape)
尽管如此,有时,当我尝试调整图像大小时,该手势被解释为在某个形状上的拖动手势,该手势执行对该形状上的点击(以最小距离0拖动)的逻辑,而不是调整大小(在拖动的情况下)模式,这不是问题)。
下面是主视图和形状视图的逻辑,其中实例放置在主视图内部
struct MainView: View {
@EnvironmentObject var mainviewmodel : Mainviewmodel
@State private var offset = CGSize.zero
@State private var draggedSize: CGSize = CGSize.zero
@State private var scale: CGFloat = 1.0
@State private var scaledSize: CGFloat = 1.0
var body: some View {
GeometryReader {
geometry in
ZStack {
ForEach(mainviewmodel.shapeItemKeys,id: \.self){ id in
let shapeItem = $mainviewmodel.shapeItemsByKey[id]
ShapeView(shapeItem: shapeItem,dragGestureMode: $mainviewmodel.dragGestureMode)
}
}
.frame(width: min(geometry.size.width,geometry.size.height),height: min(geometry.size.width,alignment: .center)
.contentShape(Rectangle())
.offset(x: self.draggedSize.width,y: self.draggedSize.height)
.scaleEffect(self.scaledSize)
.gesture(
DragGesture()
.onChanged { gesture in
self.draggedSize = gesture.translation
self.draggedSize.width += self.offset.width
self.draggedSize.height += self.offset.height
}
.onEnded { _ in
self.offset = self.draggedSize
}
)
.gesture(MagnificationGesture()
.onChanged({ (scale) in
self.scaledSize = scale.magnitude
self.scaledSize *= self.scale
})
.onEnded({ (scaleFinal) in
self.scale = scaleFinal
print("New scale: \(self.scale)")
self.scale = self.scaledSize
}))
}
}
}
struct ShapeView: View {
@Binding var shapeItem: ShapeItem?
@Binding var dragGestureMode: DragGestureEnum
var layersToRemove: [Int] = []
init(shapeItem: Binding<ShapeItem?>,dragGestureMode: Binding<DragGestureEnum>) {
self._shapeItem = shapeItem
self._dragGestureMode = dragGestureMode
}
var body: some View {
ZStack {
shapeItem!.path
.foregroundColor(Color(shapeItem!.color))
.overlay(
ZStack {
// ... some logic
},alignment: .leading)
.gesture(
DragGesture(minimumdistance: 0,coordinateSpace: .global)
.onChanged { gesture in
print("Tap location: \(gesture.startLocation)")
}
)
.allowsHitTesting(dragGestureMode == DragGestureEnum.TransformShape)
}
}
}
在这种情况下(即应在形状视图上检测到轻敲,在形状视图上应检测到拖动或调整大小),是否有人知道启用手势组合((拖动或调整大小)或(轻击或调整大小))的一种好方法?主视图和在各个形状上的点击以及在主视图上的拖动是独占的),以便获得预期的用户体验(防止将大小调整的手势解释为点击或拖动)?
解决方法
您可以使用同时手势修饰符,例如
.simultaneousGesture(MagnificationGesture()
...