swipeActions on macOS?

Has anyone tried doing macOS dev with SwiftUI?

In particular, tried using the swipeActions functionality with a List on macOS?

I can't get it to work in my own project, or in a smaller example.

Here is a short example from Paul Hudson:

Here is the code – sorry, it seems you cannot link to Paul's site in these forums:

struct ContentView: View {
    var body: some View {
        List {
            Text("Pepperoni pizza")
                .swipeActions {
                    Button("Order") {
                        print("Awesome!")
                    }
                    .tint(.green)
                }
    
            Text("Pepperoni with pineapple")
                .swipeActions {
                    Button("Burn") {
                        print("Right on!")
                    }
                    .tint(.red)
                }
        }
    }
}

Works great in iOS 15 beta running in the Simulator. Exactly as you'd expect.

Doesn’t work at all on macOS Monterey beta when dropped into a project targeting macOS 12.0.

Is there something else one needs to do to manipulate list items using a swipe action on macOS?

The documentation states this is supported on macOS 12.0+.

Any thoughts or suggestions would be much appreciated.

Answered by ForumsContributor in

works without any problems for me on macos 12.beta (latest), xcode 13.beta, target macos 12.

Accepted Answer

I was able to work this out – the issue is that swipeActions seem to be limited to three-column navigation scenarios.

I was attempting to use .swipeAction modifiers in a layout with only two columns.

For completeness and an answer to my original question, here is a modification of the code from Alex Grebenyuk's "Triple Trouble" blog post from February 14, 2021, illustrating how to get a swipe action to work.

All I did was take Alex's code from his blog post, and add the .swipeAction modifier.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            Sidebar()
            Text("No Sidebar Selection")
            Text("No Message Selection")
        }
    }
}

struct Sidebar: View {
    @State private var isDefaultItemActive = true
    
    var body: some View {
        List {
            Text("Favorites")
                .font(.caption)
                .foregroundColor(.secondary)
            NavigationLink(destination: InboxView(), isActive: $isDefaultItemActive) {
                Label("Inbox", systemImage: "tray.2")
            }
            NavigationLink(destination: SentView()) {
                Label("Sent", systemImage: "paperplane")
            }
        }.listStyle(SidebarListStyle())
    }
}

struct InboxView: View {
    var body: some View {
        List(Array(0...100).map(String.init), id: \.self) { message in
            NavigationLink(destination: MessageDetailsView(message: message)) {
                Text(message)
            }
            .swipeActions {
                Button("Order") {
                    print("Awesome!")
                }
                .tint(.green)
            }
        }
        .navigationTitle("Inbox")
        .toolbar {
            Button(action: { /* Open filters */ }) {
                Image(systemName: "line.horizontal.3.decrease.circle")
            }
        }
    }
}

struct SentView: View {
    var body: some View {
        Text("No Sent Messages")
            .navigationTitle("Sent")
            .toolbar {
                Button(action: {}) {
                    Image(systemName: "line.horizontal.3.decrease.circle")
                }
            }
    }
}

struct MessageDetailsView: View {
    let message: String
    
    var body: some View {
        Text("Details for \(message)")
            .toolbar {
                Button(action: {}) {
                    Image(systemName: "square.and.arrow.up")
                }
            }
    }
}

I have to admit though, I'm still a bit curious about why this doesn't seem to work for me in a two-column layout.

The Messages app on macOS is an example of a swipe action occurring without having three columns.

So, I'm still not certain about the conditions under which the .swipeAction modifier will work.

The key is to use a Label for it to work on macOS

example:

Text("aaa")
.swipeActions {
    Button {
      //Do something
    } label: {
        Label("Delete", systemImage: "trash") //Use a label
    }

Even with two columns and a Label. It does not work for me. I am using Xcode 14 and Monterey

var body: some View {
        VStack {
            List(podcast.episodes!) { episode in
                EpisodeView(podcast: podcast, episode: episode)
                    .swipeActions(edge: .trailing) {
                        Button (action: { self.deleteEpisode(episode) }) {
                            Label("Delete", systemImage: "trash")
                        }
                        .tint(.red)
                    }
            }
        }
    }

I am trying to make this work on macOS13 with Xcode 14.1

swipeActions on macOS?
 
 
Q