简体   繁体   English

如何在 Swift 中首次按下按钮时添加触觉,而不是在释放按钮之后?

[英]How can I add haptics on initial press of a button in Swift, not after the button has been released?

I'm familiar with UIImpactFeedbackGenerator, and that you have to use it in a button's action rather than with.onTapGesture.我熟悉 UIImpactFeedbackGenerator,你必须在按钮的操作中使用它而不是 with.onTapGesture。 What I can't figure out is how to get the haptics to trigger on the initial button press instead of on button release.我想不通的是如何让触觉在初始按钮按下而不是按钮释放时触发。

I initially tried this code and it only works on button release:我最初尝试了这段代码,它只适用于按钮释放:

struct HapticButton: View {
    var body: some View {
        
        Button {
            
            let impactLight = UIImpactFeedbackGenerator(style: .light)
            impactLight.impactOccurred()
            
        } label: {
            
            Text("Haptic Button")
            
        }
        
    }
}

Then I tried using the simultaneousGesture modifier with DragGesture, and it achieves the haptic effect as soon as the button is pressed — however , it also repeats the haptic every time you drag your finger around the screen after button press.然后我尝试将 simultaneousGesture 修改器与 DragGesture 一起使用,它在按下按钮时立即实现了触觉效果——但是,每次按下按钮后在屏幕上拖动手指时它也会重复触觉。 That would be great for a color change that you want to maintain, but not so good for a haptic event.这对于您想要保持的颜色变化非常有用,但对于触觉事件则不太好。 Here's what that code looks like:该代码如下所示:

struct HapticButton: View {
    var body: some View {
        
        Button {
            
            let impactLight = UIImpactFeedbackGenerator(style: .light)
            impactLight.impactOccurred()
            
        } label: {
            
            Text("Haptic Button")
            
        }
        .simultaneousGesture(
            DragGesture(minimumDistance: 0)
                .onChanged({ _ in
                    
                    let impactLight = UIImpactFeedbackGenerator(style: .light)
                    impactLight.impactOccurred()
                    
                })
        )
    }
}

Any tips on how to only apply the haptic effect one time on initial press?关于如何在初次按下时仅应用一次触觉效果的任何提示? For an example of the behavior I'm seeking, check the iOS keyboard.有关我正在寻找的行为示例,请查看 iOS 键盘。 The haptic occurs as soon as you touch they key, not after you release it, and not repeatedly if you drag.触觉会在您触摸它们的键时立即发生,而不是在您释放它之后发生,并且如果您拖动则不会重复发生。

Extending your proposed solution, we could create a custom view modifier.扩展您提出的解决方案,我们可以创建一个自定义视图修改器。 We can track whether DragGesture started and trigger a haptic effect only for the initial press.我们可以跟踪 DragGesture 是否启动并仅针对初始按下触发触觉效果。

struct HapticOnTouch: ViewModifier {
    @State var isDragging: Bool = false

    func body(content: Content) -> some View {
        content
            .simultaneousGesture(
                DragGesture(minimumDistance: 0)
                    .onChanged { _ in
                        if !isDragging {
                            let impactLight = UIImpactFeedbackGenerator(style: .light)
                            impactLight.impactOccurred()
                        }

                        isDragging = true
                    }
                    .onEnded { _ in
                        isDragging = false
                    }
            )
    }
}

extension View {
    func hapticOnTouch() -> some View {
        modifier(HapticOnTouch())
    }
}

Then you can apply this effect to any view or button like this:然后您可以将此效果应用于任何视图或按钮,如下所示:

Button {
    // perform action
} label: {
    Text("Haptic Button")
}
.hapticOnTouch()

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

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