How to create haptic feedback for a Button in SwiftUI?

前端 未结 4 1982
伪装坚强ぢ
伪装坚强ぢ 2021-02-12 22:15

I\'m trying to implement haptic feedback at the beginning of a tap for a Button in SwiftUI. Therefore I\'m trying to use simultaneousGesture, but I\'m sill struggling. I can\'t

4条回答
  •  旧巷少年郎
    2021-02-12 22:54

    pure SwiftUI solution below:

    HStack {
        Image("icon")
        Text("Login")
    }
    .onTouchGesture(
        touchBegan: { self.generateHapticFeedback = true },
        touchEnd: { _ in self.generateHapticFeedback = false }
    )
    

    Just add this snippet somewhere in your project:

    struct TouchGestureViewModifier: ViewModifier {
        let touchBegan: () -> Void
        let touchEnd: (Bool) -> Void
    
        @State private var hasBegun = false
        @State private var hasEnded = false
    
        private func isTooFar(_ translation: CGSize) -> Bool {
            let distance = sqrt(pow(translation.width, 2) + pow(translation.height, 2))
            return distance >= 20.0
        }
    
        func body(content: Content) -> some View {
            content.gesture(DragGesture(minimumDistance: 0)
                    .onChanged { event in
                        guard !self.hasEnded else { return }
    
                        if self.hasBegun == false {
                            self.hasBegun = true
                            self.touchBegan()
                        } else if self.isTooFar(event.translation) {
                            self.hasEnded = true
                            self.touchEnd(false)
                        }
                    }
                    .onEnded { event in
                        if !self.hasEnded {
                            let success = !self.isTooFar(event.translation)
                            self.touchEnd(success)
                        }
                        self.hasBegun = false
                        self.hasEnded = false
                    })
        }
    }
    
    extension View {
        func onTouchGesture(touchBegan: @escaping () -> Void = {},
                            touchEnd: @escaping (Bool) -> Void = { _ in }) -> some View {
            modifier(TouchGestureViewModifier(touchBegan: touchBegan, touchEnd: touchEnd))
        }
    }
    

提交回复
热议问题