简体   繁体   English

列表中的 SwiftUI NavigationLink 没有使用 isActive 获得正确的详细信息页面

[英]SwiftUI NavigationLink in the list doesn't get the right detail page with isActive

I just want to simply navigate to a detail page from a List if press any cell.如果按任何单元格,我只想简单地从List导航到详细信息页面。 I have a list like this:我有一个这样的列表: 在此处输入图像描述

When I click cell c it gets d or others.当我单击单元格c时,它会得到d或其他。 Rather than this page.而不是这个页面。

在此处输入图像描述

Here is my code:这是我的代码:

struct ContentView: View {

    var items = ["a", "b", "c", "d"]
    @State var isCellSelected = false

    var body: some View {
        NavigationView {
            List {
                ForEach(items.indices, id: \.self) { index in

                    NavigationLink(
                        destination: Text("\(items[index])"),
                                        isActive: $isCellSelected,
                        label: {
                                    RowView(text: items[index])
                        })
                }
            }
        }

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct RowView: View {

    var text: String
    var body: some View {
        VStack {
            Text(text)
        }
    }
}

If I remove isActive: $isCellSelected then it works as expected.如果我删除isActive: $isCellSelected然后它按预期工作。 I need to use isCellSelected to pop back to root view.我需要使用 isCellSelected 弹回根视图。 Not sure how to fix this issue.不知道如何解决这个问题。

Any help?有什么帮助吗? thanks!谢谢!

EDIT编辑

Update removed isActive and try set selection = nil更新删除isActive并尝试设置selection = nil

truct DetailView: View {

    var text: String
    @Binding var isCellSelected: Int?

    var body: some View {
        VStack {
            Text(text)
            Button("Back") {
                isCellSelected = nil
               }
        }
    }
}

struct ContentView: View {

    var items = ["a", "b", "c", "d"]
    @State var selectedTag: Int? = nil
    var body: some View {
        NavigationView {
            List {
                ForEach(items.indices, id: \.self) { index in

                    NavigationLink(
                        destination: DetailView(text: "\(items[index])", isCellSelected: $selectedTag),
                        tag: index,
                                                selection: $selectedTag,
                        label: {
                            RowView(text: items[index])
                        })
                }
            }
        }

    }
}

When press Back button, doesn't go back.当按下Back按钮时,go 不会返回。

It is not recommended to share a single isActive state among multiple NavigationLink s.不建议在多个NavigationLink之间共享单个isActive state。

Why don't you use selection instead of isActive ?为什么不使用selection而不是isActive

struct ContentView: View {
    
    var items = ["a", "b", "c", "d"]
    @State var selectedTag: Int? = nil //<-
    
    var body: some View {
        NavigationView {
            List {
                ForEach(items.indices, id: \.self) { index in
                    
                    NavigationLink(
                        destination: Text("\(items[index])"),
                        tag: index, //<-
                        selection: $selectedTag, //<-
                        label: {
                            RowView(text: items[index])
                        })
                }
            }
        }
        
    }
}

You can set nil to selectedTag to pop back.您可以将nil设置为selectedTag以弹回。 Seems NavigationLink in List does not work as I expect.似乎List中的NavigationLink无法按我的预期工作。 Searching for workarounds and update if found.寻找解决方法并在找到时进行更新。


A dirty workaround:一个肮脏的解决方法:

(Tested with Xcode 12.3/iPhone simulator 14.3. Please do not expect this to work on other versions of iOS including future versions.) (用 Xcode 12.3/iPhone 模拟器 14.3 测试。请不要指望这适用于 iOS 的其他版本,包括未来版本。)

struct DetailView: View {

    var text: String
    @Binding var isCellSelected: Bool

    var body: some View {
        VStack {
            Text(text)
            Button("Back") {
                isCellSelected = false
            }
        }
    }
}
struct Item {
    var text: String
    var isActive: Bool = false
}
struct ContentView: View {

    @State var items = ["a", "b", "c", "d"].map {Item(text: $0)}
    @State var listId: Bool = false //<-

    var body: some View {
//        Text(items.description) // for debugging
        NavigationView {
            List {
                ForEach(items.indices) { index in
                    NavigationLink(
                        destination:
                            DetailView(text: "\(items[index].text)",
                                       isCellSelected: $items[index].isActive)
                            .onAppear{ listId.toggle() } //<-
                        ,
                        isActive: $items[index].isActive,
                        label: {
                            RowView(text: items[index].text)
                        })

                }
            }
            .id(listId) //<-
        }
    }
}

Another workaround:另一种解决方法:

struct DetailView: View {

    var text: String
    @Binding var isCellSelected: Int?

    var body: some View {
        VStack {
            Text(text)
            Button("Back") {
                isCellSelected = nil
            }
        }
    }
}
struct ContentView: View {

    var items = ["a", "b", "c", "d"]
    @State var selectedTag: Int? = nil

    var body: some View {
        NavigationView {
            ZStack {
                ForEach(items.indices) { index in
                    NavigationLink(
                        destination:
                            DetailView(text: "\(items[index])",
                                       isCellSelected: $selectedTag),
                        tag: index,
                        selection: $selectedTag,
                        label: {
                            EmptyView()
                        })
                }
                List {
                    ForEach(items.indices) { index in
                        Button(action: {
                            selectedTag = index
                        }) {
                            HStack {
                                RowView(text: items[index])
                                Spacer()
                                Image(systemName: "chevron.right")
                                    .foregroundColor(Color.secondary)
                            }
                        }
                    }
                }
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 NavigationLink、isActive 在 SwiftUI 中不起作用 - NavigationLink, isActive doesn´t work in SwiftUI NavigationLink 不适用于 SwiftUI 列表中的 ScrollView - NavigationLink doesn't work with ScrollView inside a List in SwiftUI 在 SwiftUI 中使用 List 时如何使用 NavigationLink isActive 绑定? - How does one use NavigationLink isActive binding when working with List in SwiftUI? SwiftUI NavigationLink 不会使用 onReceive 方法触发 - SwiftUI NavigationLink doesn't trigger with onReceive method 无法单击列表(SwiftUI)中的NavigationLink - Can't click a NavigationLink in List (SwiftUI) SwiftUI 如果我将 NavigationLink 和 a.contextMenu 添加到列表中,则不显示列表选择。 这是一个已知的错误? - SwiftUI List selection doesn’t show If I add a NavigationLink and a .contextMenu to the list. Is this a known bug? SwiftUI 列表与 NavigationLink 和按钮 - SwiftUI List with NavigationLink and Buttons SwiftUI 不会在嵌套 NavigationLink 目标中使用 ObservedObject 更新 UI - SwiftUI doesn't update UI with ObservedObject in nested NavigationLink destination 强制一个 NavigationLink 到 SwiftUI 中的详细视图 - Force one NavigationLink to the detail view in SwiftUI SwiftUI - 表单中的 NavigationLink 单元格在详细信息弹出后保持突出显示 - SwiftUI - NavigationLink cell in a Form stays highlighted after detail pop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM