簡體   English   中英

如何啟用多個手勢?

[英]How to enable multiple gestures?

我創建了一個應用程序,它由主視圖組成,其中有多個視圖,每個形狀一個。 對於形狀,我想啟用一些交互,以便在點擊時轉換其屬性。 由於轉換也取決於點擊位置,因此我通過以下方式將其實現為 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)
        }
    }
}

有誰知道在這種情況下啟用手勢組合((拖動或調整大小)或(點擊或調整大小))的好方法(即應在形狀視圖上檢測到點擊,應在主視圖上檢測到拖動或調整大小和點擊單個形狀並在主視圖上拖動是專有的)以獲得預期的用戶體驗(防止調整大小手勢被解釋為點擊或拖動)?

您可以同時使用手勢修飾符,例如

    .simultaneousGesture(MagnificationGesture()
      ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM