SkillAgentSearch skills...

SwipeActions

Swipe actions for any view, swipe menu based on SwiftUI, full swiping and RTL languages supporting, iOS 13+, add your own views to swipes

Install / Use

/learn @c-villain/SwipeActions
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

SwipeActions

Latest release

contact: @lexkraev Telegram Group

<p align="left"> <img src="Sources/Gifs/teaser.jpg" alt="corner radius" width="600"> </p>

Library for creating fully customizable swipe actions for any SwiftUI View, similar to Apple's swipeActions(edge:allowsFullSwipe:content:) that available from iOS 15 and only in List 🤷🏼‍♂️. You can use SwipeActions in project targeting iOS 13 with any view (e.g. Text or VStack).

👨🏻‍💻 Feel free to subscribe to channel SwiftUI dev in telegram.

Requirements

  • iOS 13.0 or macOS 10.15

Comparison table

| Features support | This SPM | Others | | :--- | :---: | :---: | | SwiftUI | 🟢 | 🟢 | | SPM | 🟢 | 🟢 | | MacOS | 🟢 | 🔴 | | iOS 13.0 | 🟢 | 🔴 | | RTL Languages | 🟢 | 🔴 | | FullSwipe Mode | 🟢 | 🔴 | | Flexibility | 🟢 | 🟡 | | Haptics | 🟢 | 🟡 | | Ease of Use | 🟢 | 🔴 |


Installation

Swift Package Manager

To integrate SwipeActions into your project using SwiftPM add the following to your Package.swift:

dependencies: [
    .package(url: "https://github.com/c-villain/SwipeActions", from: "0.1.0"),
],

or via XcodeGen insert into your project.yml:

name: YourProjectName
options:
  deploymentTarget:
    iOS: 13.0
packages:
  SwipeActions:
    url: https://github.com/c-villain/SwipeActions
    from: 0.1.0
targets:
  YourTarget:
    type: application
    ...
    dependencies:
       - package: SwipeActions

Types

Different types of menu:

  • .swiped
  • .slided
<p align="center"> <img src="Sources/Gifs/menuTypes.gif" alt="Example for .swiped and .slided menu" height="100" width="280"> </p>

Both types can be upgraded with full swiping:

<p align="center"> <img src="Sources/Gifs/fullSwipe.gif" alt="Example of full swipe with non-destructive role" width="280"> </p>

Quick start

<details> <summary>Adding both leading and trailing swipe actions:</summary> <p align="center"> <img src="Sources/Gifs/both.gif" alt="Example with leading and trailing swipes" height="160" width="280"> </p>

Use Leading { ... } and Trailing { ... } closures inside .addSwipeAction { ... } modifier:

import SwipeActions

struct YourView: View {
    
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(1...100, id: \.self) { cell in
                    Text("Cell \(cell)")
                        .frame(height: 50, alignment: .center)
                        .frame(maxWidth: .infinity)
                        .contentShape(Rectangle())
                        .addSwipeAction {
                            Leading { //<= HERE 
                                Button {
                                    print("edit \(cell)")
                                } label: {
                                    Image(systemName: "pencil")
                                        .foregroundColor(.white)
                                }
                                .frame(width: 60, height: 50, alignment: .center)
                                .contentShape(Rectangle())
                                .background(Color.green)

                            }
                            Trailing { //<= HERE 
                                HStack(spacing: 0) {
                                    Button {
                                        print("remove \(cell)")
                                    } label: {
                                        Image(systemName: "trash")
                                            .foregroundColor(.white)
                                    }
                                    .frame(width: 60, height: 50, alignment: .center)
                                    .contentShape(Rectangle())
                                    .background(Color.red)
    
                                    Button {
                                        print("Inform \(cell)")
                                    } label: {
                                        Image(systemName: "bell.slash.fill")
                                            .foregroundColor(.white)
                                    }
                                    .frame(width: 60, height: 50, alignment: .center)
                                    .background(Color.blue)
                                }
                            }
                        }
                }
            }
        }
    }
}
</details> <details> <summary>Adding several actions on the side:</summary>

Don't forget that your actions are subviews in general and buttons or smth else particularly. Please arrange them:

YourView()
.addSwipeAction(edge: .trailing) {
    HStack(spacing: 0) { // <= 👀 Look here 
        Rectangle()
            .fill(Color.green.opacity(0.8))
            .frame(width: 8.0, height: 80)
        
        Button {
        } label: {
            Image(systemName: "message")
                .foregroundColor(.white)
                .frame(width: 60, height: 80)
                .contentShape(Rectangle())
        }
        .background(Color.blue)
    }
}

</details> <details> <summary>Adding swipe actions to the one side of the view:</summary> <p align="center"> <img src="Sources/Gifs/trailing.gif" alt="Example with trailing swipe menu" height="160" width="280"> </p>

Use .addSwipeAction(edge: ) { ... } modifier, edge - a HorizontalAlignment value input parameter - with two cases of using .leading or .trailing

import SwipeActions

struct YourView: View {
    
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(1...100, id: \.self) { cell in
                    Text("Cell \(cell)")
                        .frame(height: 50, alignment: .center)
                        .frame(maxWidth: .infinity)
                        .contentShape(Rectangle())
                        .addSwipeAction(edge: .trailing) { // <= choose here .trailing or .leading
                            HStack(spacing: 0) {
                                Button {
                                    print("remove \(cell)")
                                } label: {
                                    Image(systemName: "trash")
                                        .foregroundColor(.white)
                                }
                                .frame(width: 60, height: 50, alignment: .center)
                                .contentShape(Rectangle())
                                .background(Color.red)
                                
                                Button {
                                    print("Inform \(cell)")
                                } label: {
                                    Image(systemName: "bell.slash.fill")
                                        .foregroundColor(.white)
                                }
                                .frame(width: 60, height: 50, alignment: .center)
                                .background(Color.blue)
                            }
                        }
                }
            }
        }
    }
}
</details> <details> <summary>For automatically closing other opened actions during sliding: </summary> <p align="center"> <img src="Sources/Gifs/autoclosing.gif" alt="Example with auto closing swipe actions" width="280"> </p>

Add SwipeState var to your View and pass it as a binding in .addSwipeAction(state:):


struct YourView: View {  
   @State var state: SwipeState = .untouched // <= HERE

   var body: some View {
        ScrollView {
             VStack(spacing: 2) {
                 ForEach(1 ... 30, id: \.self) { cell in
                     Text("Cell \(cell)")
                         .addSwipeAction(state: $state) { // <= HERE
                            ....
                         }
                  }
             }
        }
   }
}
</details>

Full swipe action

For full swipe use modifier .addFullSwipeAction(menu:swipeColor:swipeRole:state:content:action:)

Basically there are two main SwipeRole for full swipe action: .destructive (defaults) and other one.

<details> <summary>.destructive</summary>

This role is used for closing/hiding/removing cell.

<p align="center"> <img src="Sources/Gifs/destructiveFullSwipe.gif" alt="Example of full swipe with destructive role" width="280"> </p>

struct YourView: View {  
   
   @St

Related Skills

View on GitHub
GitHub Stars284
CategoryCustomer
Updated4d ago
Forks39

Languages

Swift

Security Score

100/100

Audited on Mar 28, 2026

No findings