Enable and Disable SwiftUI List rows reordering on a specific row
Table of Contents
We can easily enable List row reordering in SwiftUI by attach .onMove
modifier to the list content.
struct ReorderExample: View {
@State private var contacts = [...]
var body: some View {
NavigationView {
List {
ForEach(contacts, id: \.self) { contact in
Text(contact)
}
.onMove { from, to in
contacts.move(fromOffsets: from, toOffset: to)
}
}
.toolbar {
EditButton()
}
}
}
}
This will enable item reordering on every row. If you want to prevent some rows from moving, you can do that by using moveDisabled(_:)
on that particular row.
You can easily support sarunw.com by checking out this sponsor.
Debug 10x faster with Proxyman: Your ultimate tool to capture HTTPs requests/ responses, natively built for your iPhone and macOS. Special deal for Black Friday: Get 30% off for all Proxyman licenses with code “BLACKFRIDAY2024”.
How to disable item reordering on a specific row
To disable item reordering on a particular row, you might want to add a new property in your data model to dictate that the item can't be moved.
In this case, I create a sticky
flag in my model.
struct Contact: Identifiable {
let id = UUID()
let name: String
let sticky: Bool
}
Then mark the item you want to disable reordering by setting sticky
to true
.
@State private var contacts = [
Contact(name: "John", sticky: false),
Contact(name: "Alice", sticky: true),
Contact(name: "Bob", sticky: true),
Contact(name: "Foo", sticky: false),
Contact(name: "Bar", sticky: false)
]
Then inside each row, you use that sticky
flag to set .moveDisabled(contact.sticky)
modifier.
struct DisableMoveExample: View {
@State private var contacts = [
Contact3(name: "John", sticky: false),
Contact3(name: "Alice", sticky: true),
Contact3(name: "Bob", sticky: true),
Contact3(name: "Foo", sticky: false),
Contact3(name: "Bar", sticky: false)
]
var body: some View {
NavigationView {
List {
ForEach(contacts) { contact in
Text(contact.name)
.moveDisabled(contact.sticky)
}.onMove { from, to in
contacts.move(fromOffsets: from, toOffset: to)
}
}
.toolbar {
EditButton()
}
}
}
}
Run the app again, and the rows which have .moveDisabled
set to true
won't have the drag handler UI.
Read more article about SwiftUI, List, or see all available topic
Enjoy the read?
If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.
Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.
If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.
Become a patron Buy me a coffee Tweet ShareUnwrap Swift optional value in Switch case
Learn how to test for unwrapped optional values in a switch statement.
Using SwiftUI in UIKit as UIViewController
We can use SwiftUI view in UIKit by wrapping it in UIViewController. Let's learn how to do it.