Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any SwiftUI Button equivalent to UIKit's "touch down", i.e. activate button when your finger touches?

For SwiftUI the default button behavior is equivalent to UIKit's "touch up inside", which activates when your finger touches the button then raises while within the bounds of the button.

Is there any way to change this to "touch down" so the action closure is run immediately when your finger touches the button?

like image 320
RogerTheShrubber Avatar asked Sep 09 '19 20:09

RogerTheShrubber


People also ask

How do I make a button clickable in SwiftUI?

SwiftUI's button is similar to UIButton , except it's more flexible in terms of what content it shows and it uses a closure for its action rather than the old target/action system. To create a button with a string title you would start with code like this: Button("Button title") { print("Button tapped!") }

How do I programmatically click a button in SwiftUI?

For example: you can run actionOfButton() from the place you want programmatically tap the Button, it would work the same.

What is a button SwiftUI?

A Button is a type of control that performs an action when it is triggered. In SwiftUI, a Button typically requires a title text which is the text description of your button, and an action function that will handle an event action when triggered by the user.

How do you round a button in SwiftUI?

Any SwiftUI view can have its corners rounded using the cornerRadius() modifier. This takes a simple value in points that controls how pronounced the rounding should be.


2 Answers

You can use a DragGesture with a minimumDistance of zero and define a closure for DOWN (onChanged()) or UP (onEnded()):

struct ContentView: View {
    @State private var idx = 0

    var body: some View {
        let g = DragGesture(minimumDistance: 0, coordinateSpace: .local).onChanged({
            print("DOWN: \($0)")
        }).onEnded({
            print("UP: \($0)")
        })

        return Rectangle().frame(width: 100, height: 50).gesture(g)
    }
}
like image 151
kontiki Avatar answered Sep 19 '22 17:09

kontiki


You can create a custom view modifier:

extension View {
    func onTouchDownGesture(callback: @escaping () -> Void) -> some View {
        modifier(OnTouchDownGestureModifier(callback: callback))
    }
}

private struct OnTouchDownGestureModifier: ViewModifier {
    @State private var tapped = false
    let callback: () -> Void

    func body(content: Content) -> some View {
        content
            .simultaneousGesture(DragGesture(minimumDistance: 0)
                .onChanged { _ in
                    if !self.tapped {
                        self.tapped = true
                        self.callback()
                    }
                }
                .onEnded { _ in
                    self.tapped = false
                })
    }
}

struct MyView: View {
    var body: some View {
        Text("Hello World")
            .onTouchDownGesture {
                print("View did tap!")
            }
    }
}
like image 41
matteopuc Avatar answered Sep 19 '22 17:09

matteopuc