SwiftUI touchUpInside ?

Is there an equivalent of “touchUpInside” in SwiftUI?


In UIKit, it was very easy to look for a touchUpInside event.


With SwiftUI, we can attach a “tapAction”, but this will require re-training users to always be “quick and decisive” in their actions.


Any hope for a more deliberative, slow-fingered user?

Replies

Thanks for answers in https://forums.developer.apple.com/thread/119202 for some help by pointing out using a DragGesture with a minimum distance of 0. This has helped in developing the following code to partially emulate a button. It gets a flash effect that ends when the gesture is finished. It still doesn't handle the "inside" part of touchUpInside - that detects if the touch is still inside before taking final action. The code creates a ViewModifier to make it easy to apply the flash effect.


import SwiftUI

struct PressedView: ViewModifier {
    // Produces a "flash" overlay when pressed
    @Binding var isPressed: Bool
    let myWhite = Color.init(.sRGB, white: 1, opacity: 0.5)
    let myWhite2 = Color.init(.sRGB, white: 1, opacity: 0.25)
    
    func body(content: Content) -> some View {
        if isPressed {
            return content.overlay(Color.clear.background(RadialGradient(gradient: Gradient(colors: [ myWhite, myWhite2]), center: .center, startRadius:  10, endRadius: 100), cornerRadius: 0))
        } else {
            // NOTE: tried to return something simpler, but Swift required matching return values.  So, returning overlay with clear stuff
            return content.overlay(Color.clear.background(RadialGradient(gradient: Gradient(colors: [ .clear, .clear]), center: .center, startRadius:  10, endRadius: 100), cornerRadius: 0))
        }
    }
}

struct FlashButton : View {
    @State private var isPressed = false
    var text: String
    
    var body: some View {
        let dragGesture = DragGesture(minimumDistance: 0.0)
            .onChanged { _ in self.isPressed = true  }
            .onEnded {  _ in self.isPressed = false }
        
        return Text(self.text)
            .color(Color.accentColor)
            .modifier(PressedView(isPressed: $isPressed))
            .gesture(dragGesture)
    }
}

#if DEBUG
struct FlashButton_Previews : PreviewProvider {
    static var previews: some View {
        FlashButton(text: "Test")
    }
}
#endif