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