简体   繁体   English

SwiftUI 中的“触摸进入”手势

[英]Gesture for "touch enters" in SwiftUI

I am displaying a series of looped views using a VStack .我正在使用VStack显示一系列循环视图。 When the user taps down on one of these views, it is highlighted.当用户点击这些视图之一时,它会突出显示。 In order to get the highlight to show on a touch down, and not when a touch is released, I used a DragGesture with a minimumDistance value of 0 :为了让高光在触地时显示,而不是在释放触摸时显示,我使用了minimumDistance值为0DragGesture

private func highlightGesture(_ i: Int) -> some Gesture {
  DragGesture(minimumDistance: 0.0)
    .onChanged { _ in highlight = i }
    .onEnded { _ in highlight = nil }
}

However, I want the highlight to update when the user's drag gesture enters another view.但是,我希望在用户的拖动手势进入另一个视图时更新突出显示。 For instance, if I tap and highlight the first view, then move my finger over to the second view without taking it off the screen, it should highlight the second view.例如,如果我点击并突出显示第一个视图,然后将手指移到第二个视图而不将其从屏幕上移开,它应该突出显示第二个视图。

With the gesture shown above, a view is only highlighted when it is tapped.使用上面显示的手势,只有在点击视图时才会突出显示视图。 Instead, I'd like the view to be highlighted when it is tapped or when touch enters the view.相反,我希望在点击触摸进入视图时突出显示视图。

Any help is greatly appreciated.任何帮助是极大的赞赏。

here is a simple example that shows a possible way to drag your finger across 2 views/images and highlight them when it enters the different views/images.这是一个简单的示例,它显示了一种可能的方式,即在 2 个视图/图像上拖动手指并在进入不同的视图/图像时突出显示它们。 You will have to do a lot more work with this.你将不得不做更多的工作。 Hope it helps.希望能帮助到你。

struct ContentView: View {

class ImgObj: ObservableObject {
    @Published var img1Rec: CGRect = CGRect.zero
    @Published var img2Rec: CGRect = CGRect.zero
    @Published var img1Color: Color = .black
    @Published var img2Color: Color = .black
}

@ObservedObject var imgObj = ImgObj()
@GestureState var dragVar = CGSize.zero

var body: some View {
    
    let dragger = DragGesture(minimumDistance: 0.0, coordinateSpace: .global)
        .updating($dragVar, body: { (value, _, _) in
            imgObj.img1Color = imgObj.img1Rec.contains(value.location) ? .red : .black
            imgObj.img2Color = imgObj.img2Rec.contains(value.location) ? .red : .black
        })
    
    GeometryReader { geometry in
        VStack {
            Image(systemName: "clock").resizable().frame(width: 222, height: 222)
                .foregroundColor(imgObj.img1Color)
                .gesture(dragger)
                .onAppear {
                    // use geometry.frame(in: .global) somehow to get the CGRect
                    imgObj.img1Rec = CGRect(x: 0, y: 0, width: 222, height: 222)
                }
            Image(systemName: "folder").resizable().frame(width: 222, height: 222)
                .foregroundColor(imgObj.img2Color)
                .gesture(dragger)
                .onAppear {
                    // use geometry.frame(in: .global) somehow to get the CGRect
                    imgObj.img2Rec = CGRect(x: 0, y: 222, width: 222, height: 222)
                }
        }
    }
}
}

Edit note:编辑说明:

instead of:代替:

            .onAppear {
                // use geometry.frame(in: .global) somehow to get the CGRect
                imgObj.img1Rec = CGRect(x: 0, y: 222, width: 222, height: 222)
            }
            

you could use:你可以使用:

                 .background(
                    GeometryReader { proxy in
                        Color.clear
                            .onAppear {
                                imgObj.img1Rec = proxy.frame(in: .global)
                            }
                    })
                    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM