Logo for tanaschita.com

Adding swipe actions to any SwiftUI scroll view

Learn how to use swipe actions outside of List in SwiftUI.

17 Aug 2026 · 3 min read

Until iOS 27, SwiftUI's swipeActions modifier worked with rows inside a List. Starting with iOS 27, we can also add swipe actions to views inside a ScrollView.

Let's look at how to do that.

Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE

Adding swipe actions to a List

In a List, we attach the swipeActions modifier directly to each row:

List {
ForEach(tasks) { task in
TaskRow(task: task)
.swipeActions {
Button("Delete", systemImage: "trash", role: .destructive) {
delete(task)
}
}
}
}

SwiftUI's List provides the container behavior needed to reveal the action when the user swipes the row. Applying the same row modifier inside a regular ScrollView, however, is not enough.

Enabling swipe actions in a ScrollView

For a custom scroll view, we additionally apply the new swipeActionsContainer modifier to the ScrollView:

ScrollView {
LazyVStack(spacing: 12) {
ForEach(tasks) { task in
TaskRow(task: task)
.swipeActions {
Button("Delete", systemImage: "trash", role: .destructive) {
delete(task)
}
}
}
}
.padding()
}
.swipeActionsContainer()

The two modifiers have different responsibilities: swipeActions defines the actions for an individual view, while swipeActionsContainer enables the interaction for the surrounding scroll view.

Customizing swipe actions

The existing options for swipe actions work in the new container as well. For example, we can add actions to both edges and control whether a full swipe performs the first action:

TaskRow(task: task)
.swipeActions(edge: .leading, allowsFullSwipe: false) {
Button("Favorite", systemImage: "star") {
favorite(task)
}
.tint(.yellow)
}
.swipeActions(edge: .trailing) {
Button("Delete", systemImage: "trash", role: .destructive) {
delete(task)
}
}

The action labels, roles, tints, edges, and full-swipe behavior are configured just as they are for a List row. The only new part is marking the parent ScrollView as a swipe actions container.

With this small addition, we can keep native swipe interactions while using LazyVStack or another custom scrollable layout.

Sponsorship logo
Preparing for a technical iOS job interview
Preparing for a technical iOS Job Interview with over 300 questions & answers. Covering Swift & Objective-C, SwiftUI & UIKit, Combine, HTTP Networking, iOS File System, Core Data, Concurrency with async/await, Security, Automated Testing, Dependency Management, AI & Machine Learning and more.
LEARN MORE
Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE
Sponsorship logo
Become a sponsor of tanaschita.com
By publishing an article on different iOS topics every week, tanaschita.com is constantly growing in the developer community and may provide a great audience for you as a sponsor.
CLICK TO LEARN MORE

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

activitykit

widgetkit

swiftui

swift

ios

Getting started with Live Activities in SwiftUI

Build a public transport journey tracker for the Lock Screen and Dynamic Island with ActivityKit.

07 Sep 2026 · 7 min read

Latest articles and tips

© 2026 tanaschita.com

Privacy policy

Impressum