Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何启用多个手势?_Swift_Swiftui - Fatal编程技术网

Swift 如何启用多个手势?

Swift 如何启用多个手势?,swift,swiftui,Swift,Swiftui,我创建了一个由主视图组成的应用程序,其中有多个视图,每个形状一个。对于形状,我想启用一些交互,以便在轻敲时转换其属性。由于转换也取决于抽头位置,因此我将其作为DragGesture以以下方式实现: .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .global) .onChanged { gesture in print("Tap location: \(gesture.startLocation)&quo

我创建了一个由主视图组成的应用程序,其中有多个视图,每个形状一个。对于形状,我想启用一些交互,以便在轻敲时转换其属性。由于转换也取决于抽头位置,因此我将其作为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, geometry.size.height), 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)
        }
    }
}
struct MainView:View{
@环境对象变量mainViewModel:mainViewModel
@国家私有风险值偏移量=CGSize.zero
@国家私有变量draggedSize:CGSize=CGSize.zero
@国有-私有var标度:CGFloat=1.0
@国家私有变量scaledSize:CGFloat=1.0
var body:一些观点{
几何导引头{
几何
ZStack{
ForEach(mainViewModel.shapeItemKeys,id:\.self){id在中
让shapeItem=$mainViewModel.shapeItemsByKey[id]
ShapeView(shapeItem:shapeItem,DragesturMode:$mainViewModel.DragesturMode)
}
}
.frame(宽度:min(几何体.尺寸.宽度,几何体.尺寸.高度),高度:min(几何体.尺寸.宽度,几何体.尺寸.高度),对齐方式:。中心)
.contentShape(矩形())
.offset(x:self.draggedSize.width,y:self.draggedSize.height)
.scaleEffect(self.scaledSize)
.手势(
德拉格斯特尔()
.onChanged{手势在
self.draggedSize=手势.translation
self.draggedSize.width+=self.offset.width
self.draggedSize.height+=self.offset.height
}
.onEnded{uuin
self.offset=self.draggedSize
}
)
.手势
.onChanged({(比例)in
self.scaledSize=scale.magnity
self.scaledSize*=self.scale
})
.onEnded({(scaleFinal)在
self.scale=scaleFinal
打印(“新比例:\(self.scale)”)
self.scale=self.scaledSize
}))
}
}
}
结构ShapeView:视图{
@绑定变量shapeItem:shapeItem?
@绑定变量dragGestureMode:draggesturenum
var layersToRemove:[Int]=[]
init(shapeItem:Binding,dragGestureMode:Binding){
self.\u shapeItem=shapeItem
self.\u dragGestureMode=dragGestureMode
}
var body:一些观点{
ZStack{
shapeItem!路径
.foregroundColor(颜色(shapeItem!.Color))
.覆盖(
ZStack{
//…有些逻辑
}
,对齐:。前导)
.手势(
DragGesture(最小距离:0,坐标空间:。全局)
.onChanged{手势在
打印(“点击位置:\(手势.位置)”)
}
)
.allowsHitTesting(DragestureMode==DragestureNeum.TransformShape)
}
}
}

是否有人知道在这种情况下,启用手势组合(拖动或调整大小)或(轻敲或调整大小))的好方法是什么(即轻敲应在形状视图上检测到,拖动或调整大小应在主视图上检测到,轻敲单个形状并在主视图上拖动是独占的)为了获得预期的用户体验(防止将调整大小的手势解释为点击或拖动)?

您可以使用同步手势修改器,如

    .simultaneousGesture(MagnificationGesture()
      ...

如果geture在不同的视图中实现呢?这是上述示例中的情况;点击手势在形状视图中实现,调整大小手势在图像视图中实现。一个选项是在形状视图中实现调整大小和拖动,或者调整图像视图的大小,或者根据手势修改形状视图。它们是否在一个视图层次中并不重要