SwipeActions

repository·main·Indexed 23 days ago

https://github.com/aheze/swipeactions

A lightweight, 100% SwiftUI library for adding customizable swipe actions to any view. It supports drag-to-trigger gestures, programmatic control over expansion states via context, and accordion-style behavior using SwipeViewGroup. Compatible with iOS 14+.

Tokens
1.8K
Snippets
5
Records
7
Agent score
30%

What's inside SwipeActions

  1. Use SwipeViewGroup for Accordion-style behavior

    main

    To ensure that only one SwipeView is open at a time (automatically closing others when a new one is swiped), wrap your SwipeView instances in a SwipeViewGroup.

    SwipeViewGroup {
        SwipeView {} /// Only one of the actions will be shown.
        SwipeView {}
        SwipeView {}
    }
  2. Enable swiping on transparent areas

    main

    By default, SwiftUI views might not respond to gestures in empty/transparent spaces. To enable swiping across the entire area of your content, add the .contentShape(Rectangle()) modifier to the view inside the SwipeView.

    SwipeView {
        Text("Lots of empty space here.")
            .frame(maxWidth: .infinity)
            .padding(.vertical, 32)
            .contentShape(Rectangle()) /// Enable swiping on the empty space.
    } trailingActions: { _ in
        SwipeAction("Hello!") { }
    }
  3. Install SwipeActions

    main

    You can install SwipeActions using the Swift Package Manager or by manually adding the source file to your project. It requires iOS 14+.

    Swift Package Manager URL: https://github.com/aheze/SwipeActions

    Manual Installation: Since the library is contained within a single file, you can simply drag SwipeActions.swift from the repository into your Xcode project.

    https://github.com/aheze/SwipeActions
  4. Basic Usage of SwipeView and SwipeAction

    main

    To add swipe actions to a view, wrap your content in a SwipeView. You can provide leadingActions or trailingActions closures. Inside these closures, define SwipeAction instances with a label and a tap action.

    import SwiftUI
    import SwipeActions
    
    struct ContentView: View {
        var body: some View {
            SwipeView {
                Text("Hello")
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, 32)
                    .background(Color.blue.opacity(0.1))
                    .cornerRadius(32)
            } trailingActions: { _ in
                SwipeAction("World") {
                    print("Tapped!")
                }
            }
            .padding()
        }
    }
    import SwiftUI
    import SwipeActions
    
    struct ContentView: View {
        var body: some View {
            SwipeView {
                Text("Hello")
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, 32)
                    .background(Color.blue.opacity(0.1))
                    .cornerRadius(32)
            } trailingActions: { _ in
                SwipeAction("World") {
                    print("Tapped!")
                }
            }
            .padding()
        }
    }
  5. Programmatically show/hide swipe actions

    main

    You can control the expansion state of a SwipeView programmatically using the context parameter provided in the trailingActions or leadingActions closures. The context.state allows you to set the state to .expanded or .closed.

    import Combine
    import SwiftUI
    import SwipeActions
    
    struct ProgrammaticSwipeView: View {
        @State var open = PassthroughSubject<Void, Never>()
    
        var body: some View {
            SwipeView {
                Button {
                    open.send() /// Fire the `PassthroughSubject`.
                } label: {
                    Text("Tap to Open")
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 32)
                        .background(Color.blue.opacity(0.1))
                        .cornerRadius(32)
                }
            } trailingActions: { context in
                SwipeAction("Tap to Close") {
                    context.state.wrappedValue = .closed
                }
                .onReceive(open) { _ in /// Receive the `PassthroughSubject`.
                    context.state.wrappedValue = .expanded
                }
            }
        }
    }
    import Combine
    import SwiftUI
    import SwipeActions
    
    struct ProgrammaticSwipeView: View {
        @State var open = PassthroughSubject<Void, Never>()
    
        var body: some View {
            SwipeView {
                Button {
                    open.send() /// Fire the `PassthroughSubject`.
                } label: {
                    Text("Tap to Open")
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 32)
                        .background(Color.blue.opacity(0.1))
                        .cornerRadius(32)
                }
            } trailingActions: { context in
                SwipeAction("Tap to Close") {
                    context.state.wrappedValue = .closed
                }
                .onReceive(open) { _ in /// Receive the `PassthroughSubject`.
                    context.state.wrappedValue = .expanded
                }
            }
        }
    }
  6. Customize SwipeView (Main View)

    main

    Attach these modifiers to SwipeView to control the overall gesture and layout behavior:

    ModifierDescription
    swipeMinimumDistance(_ value: Double)Minimum drag distance to start the gesture.
    swipeActionsStyle(_ value: SwipeActionStyle)The style to use (mask, equalWidths, or cascade).
    swipeActionsMaskCornerRadius(_ value: Double)Corner radius encompassing all actions.
    swipeActionsVisibleStartPoint(_ value: Double)Point where actions start becoming visible.
    swipeActionsVisibleEndPoint(_ value: Double)Point where actions become fully visible.
    swipeActionCornerRadius(_ value: Double)Corner radius for each individual action.
    swipeActionWidth(_ value: Double)Width for each action.
    swipeSpacing(_ value: Double)Spacing between actions and the label view.
    swipeReadyToExpandPadding(_ value: Double)Drag point to expand actions.
    swipeReadyToTriggerPadding(_ value: Double)Drag point to enter the triggering state.
    swipeMinimumPointToTrigger(_ value: Double)Minimum drag required to trigger the edge action.
    swipeEnableTriggerHaptics(_ value: Bool)Enables haptics if swipeToTriggerLeadingEdge/swipeToTriggerTrailingEdge is true.
    swipeStretchRubberBandingPower(_ value: Double)Controls rubber banding when no actions exist or trigger is false.
    swipeAllowSingleSwipeAcross(_ value: Bool)Allows switching from leading to trailing actions in one swipe.
    swipeActionContentTriggerAnimation(_ value: Animation)Animation for adjusting content view when triggered.
    swipeOffsetCloseAnimation(stiffness: Double, damping: Double)Animation values for closing.
    swipeOffsetExpandAnimation(stiffness: Double, damping: Double)Animation values for expanding.
    swipeOffsetTriggerAnimation(stiffness: Double, damping: Double)Animation values for triggering.
  7. Customize SwipeAction (Side Views)

    main

    Attach these modifiers to a SwipeAction to control the behavior and appearance of individual side actions:

    • allowSwipeToTrigger(_ value: Bool = true): Enables drag-to-trigger for the edge action.
    • swipeActionLabelFixedSize(_ value: Bool = true): Constrains the action's content size (useful for text).
    • swipeActionLabelHorizontalPadding(_ value: Double = 16): Adds additional horizontal padding to the label.
    • swipeActionChangeLabelVisibilityOnly(_ value: Bool): Determines if only the label's opacity changes based on actionsVisibleStartPoint and actionsVisibleEndPoint.