4

I'm wondering how to place NavigationLink into swipeActions section in code below. Code itself is compiled without any issue but when I tap "Edit" link nothing happens. My intention is to show another view by tapping "Edit". Thanks

var body: some View {
    List {
        ForEach(processes, id: \.id) { process in
            NavigationLink(process.name!, destination: MeasurementsView(procID: process.id!, procName: process.name!))
                .swipeActions() {
                    Button("Delete") {
                        deleteProcess = true
                    }.tint(.red)
                    NavigationLink("Edit", destination: ProcessView(procID: process.id!, procName: process.name!)).tint(.blue)
                }
        }
    }
}

1 Answer 1

10

It does not work because swipeActions context is out of NavigationView. Instead we can use same NavigationLink for conditional navigation, depending on action.

Here is a simplified demo of possible approach - make destination conditional and use programmatic activation of link.

Tested with Xcode 13.2 / iOS 15.2

demo

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                ForEach(0..<2, id: \.id) {
                    // separate into standalone view for better
                    // state management
                    ProcessRowView(process: $0)
                }
            }
        }
    }
}

struct ProcessRowView: View {
    enum Action {
        case view
        case edit
    }
    @State private var isActive = false
    @State private var action: Action?
    let process: Int

    var body: some View {
        // by default navigate as-is
        NavigationLink("Item: \(process)", destination: destination, isActive: $isActive)
            .swipeActions() {
                Button("Delete") {

                }.tint(.red)
                Button("Edit") {
                    action = .edit    // specific action
                    isActive = true   // activate link programmatically
                }.tint(.blue)
            }
            .onChange(of: isActive) {
                if !$0 {
                    action = nil  // reset back
                }
            }
    }

    @ViewBuilder
    private var destination: some View {
        // construct destination depending on action
        if case .edit = action {
            Text("ProcessView")
        } else {
            // just to demo different type destinations
            Color.yellow.overlay(Text("MeasurementsView"))
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

What if we don't need/want a NavigationLink as the row view? I have a row which should not navigate when touched normally (and should not show the navigation carrat indicator by extension) but would like to be able to swipe to show an edit button, and tap that to go to an edit view.
I have exact same issue. So tapping the item is just for selection, swipe reveals the button to navigate to a second view...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.