| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- /// A type of tap gesture.
- public struct TapGesture: Sendable, Hashable {
- @_spi(Backends) public var kind: TapGestureKind
- /// The idiomatic "primary" interaction for the device, such as a left-click
- /// with the mouse or normal tap on a touch screen.
- public static let primary = TapGesture(kind: .primary)
- /// The idiomatic "secondary" interaction for the device, such as a
- /// right-click with the mouse or long press on a touch screen.
- public static let secondary = TapGesture(kind: .secondary)
- /// A long press of the same interaction type as ``primary``.
- ///
- /// May be equivalent to ``secondary`` on some backends, particularly on
- /// mobile devices.
- public static let longPress = TapGesture(kind: .longPress)
- @_spi(Backends) public enum TapGestureKind: Hashable, Sendable {
- case primary
- case secondary
- case longPress
- }
- }
- extension View {
- /// Adds an action to perform when the user taps or clicks this view.
- ///
- /// Any tappable elements within the view will no longer be tappable with
- /// the same gesture type.
- ///
- /// - Parameters:
- /// - gesture: The type of gesture to listen for.
- /// - action: The action to perform.
- public func onTapGesture(
- gesture: TapGesture = .primary,
- perform action: @escaping () -> Void
- ) -> some View {
- OnTapGestureModifier(body: TupleView1(self), gesture: gesture, action: action)
- }
- /// Adds an action to run when this view is clicked. Any clickable elements
- /// within the view will no longer be clickable.
- @available(*, deprecated, renamed: "onTapGesture(gesture:perform:)")
- public func onClick(perform action: @escaping () -> Void) -> some View {
- onTapGesture(perform: action)
- }
- }
- struct OnTapGestureModifier<Content: View>: TypeSafeView {
- typealias Children = TupleView1<Content>.Children
- var body: TupleView1<Content>
- var gesture: TapGesture
- var action: () -> Void
- func children<Backend: BaseAppBackend>(
- backend: Backend,
- snapshots: [ViewGraphSnapshotter.NodeSnapshot]?,
- environment: EnvironmentValues
- ) -> Children {
- body.children(
- backend: backend,
- snapshots: snapshots,
- environment: environment
- )
- }
- func asWidget<Backend: BaseAppBackend>(
- _ children: Children,
- backend: Backend
- ) -> Backend.Widget {
- func castBackend_inner<NewBackend: BaseAppBackend & BackendFeatures.TapGestures>(_ backend: NewBackend) -> NewBackend.Widget {
- return backend.createTapGestureTarget(wrapping: children.child0.widget.into(), gesture: gesture)
- }
- guard let castedBackend = backend as? any (BaseAppBackend & BackendFeatures.TapGestures) else {
- fatalError("Backend does not implement BackendFeatures.TapGestures")
- }
- return castBackend_inner(castedBackend) as! Backend.Widget
- }
- func computeLayout<Backend: BaseAppBackend>(
- _ widget: Backend.Widget,
- children: Children,
- proposedSize: ProposedViewSize,
- environment: EnvironmentValues,
- backend: Backend
- ) -> ViewLayoutResult {
- children.child0.computeLayout(
- with: body.view0,
- proposedSize: proposedSize,
- environment: environment
- )
- }
- func commit<Backend: BaseAppBackend>(
- _ widget: Backend.Widget,
- children: TupleView1<Content>.Children,
- layout: ViewLayoutResult,
- environment: EnvironmentValues,
- backend: Backend
- ) {
- func castBackend_inner<NewBackend: BaseAppBackend & BackendFeatures.TapGestures>(_ backend: NewBackend) {
- let widget = widget as! NewBackend.Widget
- let size = children.child0.commit().size
- backend.setSize(of: widget, to: size.vector)
- backend.updateTapGestureTarget(
- widget,
- gesture: gesture,
- environment: environment,
- action: action
- )
- }
- guard let castedBackend = backend as? any (BaseAppBackend & BackendFeatures.TapGestures) else {
- fatalError("Backend does not implement BackendFeatures.TapGestures")
- }
- castBackend_inner(castedBackend)
- }
- }
|