列表中的 SwiftUI NavigationLink 没有使用 isActive 获得正确的详细信息页面
Posted
技术标签:
【中文标题】列表中的 SwiftUI NavigationLink 没有使用 isActive 获得正确的详细信息页面【英文标题】:SwiftUI NavigationLink in the list doesn't get the right detail page with isActive 【发布时间】:2021-01-21 02:08:57 【问题描述】:如果按任意单元格,我只想简单地从List
导航到详细信息页面。我有一个这样的列表:
当我单击单元格c
时,它会得到d
或其他。而不是这个页面。
这是我的代码:
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)
如果我删除 isActive: $isCellSelected
,那么它会按预期工作。我需要使用 isCellSelected 弹回根视图。不知道如何解决这个问题。
有什么帮助吗?谢谢!
编辑
更新删除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])
)
当按下Back
按钮时,不返回。
【问题讨论】:
带有tag
的变体适用于 Xcode 12.1 / ios 14.1。你用的是哪个版本?
@Asperi Xcode 12.3 / iOS 14.3 模拟器。
【参考方案1】:
不建议在多个NavigationLink
s 之间共享一个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])
)
您可以将 似乎nil
设置为selectedTag
以弹回。List
中的NavigationLink
不像我预期的那样工作。搜索解决方法并在找到时进行更新。
一个肮脏的解决方法:
(使用 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) //<-
另一种解决方法:
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)
【讨论】:
嗨@OOper,我累了在详细页面中按下按钮时设置selectedTag = nil
,但它没有弹出,我编辑了我的问题,你能帮忙检查一下吗?谢谢。
@WilliamHu,你是对的。现在检查发生了什么。以上是关于列表中的 SwiftUI NavigationLink 没有使用 isActive 获得正确的详细信息页面的主要内容,如果未能解决你的问题,请参考以下文章