Swipe actions in SwiftUI

Easily add swipe actions to a row in a list.

Swipe actions on a list row is easy to implement with the new swipeActions(edge:allowsFullSwipe:content:) modifier, introduced in SwiftUI 3.0 and iOS 15. In this tutorial, let's see how to implement that!

Only on iOS 15 and higher

The swipe actions modifier is only supported in applications running on iOS 15.0 and higher. You'll need Xcode 13 and need to set your Xcode project's iOS target version to iOS 15.0 or higher, or wrap the code presented in this section in an if #available(iOS 15.0, *).

Message model

Create a message model, containing an id, a title and some content.

struct Message: Identifiable {
    var id = UUID()
    var title: String
    var content: String
}

..

Create an array of messages. Each message will follow the Message model.

var messages = [Message(title: "Hello", content: "Hello my friend, how have you been? I've been wondering if you'd like to meet up sometime."), Message(title: "50% off sales", content: "Last chance to get a hold of last season's collection, now with an additional 50% off."), Message(title: "Required documents", content: "Hi, please find attached the required documents."), Message(title: "You have 8 new followers", content: "Congrats! Since yesterday, 8 new people followed you! Log into the app to see who they are.")]

..

Message row

Each message will be displayed in its own row, with its title and content. Don't forget to pass a message to the preview so that it won't crash.

// MessageRow.swift

struct MessageRow: View {
    var message: Message

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Text(message.title)
                .font(.headline)
                .bold()

            Text(message.content)
                .foregroundColor(.gray)
                .lineLimit(2)
        }
    }
}

struct MessageRow_Previews: PreviewProvider {
    static var previews: some View {
        MessageRow(message: Message(title: "Hello", content: "Hello my friend, how have you been? I've been wondering if you'd like to meet up sometime."))
    }
}

..

Iterate through messages

In ContentView, code the basic UI layout, with a title that says My Inbox and a list that iterates through the messages. For each message, we'll display a MessageRow.

// ContentView.swift

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("My Inbox")
                .font(.title).bold()
                .padding(.horizontal)

            List(messages) { message in
                MessageRow(message: message)
            }
        }
    }
}

..

Add swipe actions

On each MessageRow, we'll add the swipeActions(edge:allowsFullSwipe:content:) modifier.

// ContentView.swift

MessageRow(message: message)
    .swipeActions {
				// Mode code...
    }

..

A swipe action accepts three possible arguments:


  • An edge, which means the edge towards which you want the swipe action to be. By default, the edge value is .trailing, meaning that users need to swipe from right to left.
  • The allowsFullSwipe value, which tells wether the user can swipe from one edge to the other to automatically perform the action. The default value is true.
  • The content or, in other words, the label you want to add to the swipe action.

In our case, we'll only add the content, which will be a button containing a Label that says Delete. The action associated with the button will only be a print to the console, saying the message has been deleted.

// ContentView.swift

.swipeActions {
		Button {
				print("Message deleted")
		} label: {
				Label("Delete", systemImage: "trash")
		}
}

..

Right now, the button is grey.

..

Let's change the color of it to red instead. To do so, we'll just need to add the tint(_:) modifier on the button.

// ContentView.swift

.swipeActions {
		Button {
				print("Message deleted")
		} label: {
				Label("Delete", systemImage: "trash")
		}
		.tint(.red)
}

..

Now, when swiping to the left, we'll see a red button to delete the message. When the action is performed, a Message deleted will be printed on the console.

..

Comments