Reputation: 946
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)
}
}
}
}
Upvotes: 4
Views: 3160
Reputation: 258443
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
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"))
}
}
}
Upvotes: 10