SwiftUI NavigationStack: 列表视图导航行为意外

huangapple go评论94阅读模式
英文:

SwiftUI NavigationStack: Unexpected Navigation Behavior from List View

问题

I'm here to provide the translated content:

我正在使用SwiftUI构建iOS应用程序,在从“List”视图导航到详细视图时遇到意外行为。

我有三个视图:ViewA、ViewB和ViewC。ViewA导航到ViewB,ViewB是一个Item实例的列表。在ViewB中点击一个Item应该导航到ViewC,显示所选Item的详细信息。

导航到ViewC的行为不正常。当我在ViewB中点击一个Item时,ViewC会短暂显示,然后立即导航回ViewB。导航堆栈在ViewB之前有ViewC。堆栈:[ViewA、ViewC、ViewB]

最小可重现的示例:

struct Item: Identifiable, Hashable {
    let id = UUID()
    let title: String
    let description: String
}

struct ViewA: View {
    var body: some View {
        NavigationStack {
            NavigationLink("转到ViewB") {
                ViewB()
            }
        }
    }
}

struct ViewB: View {
    let items: [Item] = [
        Item(title: "项目1", description: "这是项目1"),
        Item(title: "项目2", description: "这是项目2")
    ]
    
    var body: some View {
        List(items, id: \.id) { item in
            NavigationLink(value: item) {
                Text(item.title)
            }
        }
        .navigationDestination(for: Item.self) { item in
            ViewC(item: item)
        }
    }
}

struct ViewC: View {
    let item: Item

    var body: some View {
        Text(item.description)
    }
}

我期望在ViewB中选择一个Item后直接导航到ViewC,并且返回按钮应该将我带回ViewB。堆栈应该是[ViewA(根)、ViewB、ViewC]。

导致这种行为的原因是什么,我该如何解决这个问题?

英文:

I'm building an iOS app with SwiftUI and am encountering unexpected behaviour when navigating from a List view to a detail view.

I have three views: ViewA, ViewB, and ViewC. ViewA navigates to ViewB, which is a list of Item instances. Tapping on an Item in ViewB should navigate to ViewC, presenting the details of the selected Item.

The navigation to ViewC is misbehaving. When I tap an Item in ViewB, ViewC is shown briefly and then the view immediately navigates back to ViewB. The navigation stack has ViewC before ViewB. Stack: [ViewA, ViewC, ViewB]

The minimal reproducible example:

struct Item: Identifiable, Hashable {
    let id = UUID()
    let title: String
    let description: String
}

struct ViewA: View {
    var body: some View {
        NavigationStack {
            NavigationLink("Go to ViewB") {
                ViewB()
            }
        }
    }
}

struct ViewB: View {
    let items: [Item] = [
        Item(title: "Item 1", description: "This is item 1"),
        Item(title: "Item 2", description: "This is item 2")
    ]
    
    var body: some View {
        List(items, id: \.id) { item in
            NavigationLink(value: item) {
                Text(item.title)
            }
        }
        .navigationDestination(for: Item.self) { item in
            ViewC(item: item)
        }
    }
}

struct ViewC: View {
    let item: Item

    var body: some View {
        Text(item.description)
    }
}

I expect to navigate directly to ViewC when an Item is selected in ViewB and the back button should take me back to ViewB. The stack should be [ViewA (root), ViewB, ViewC].

What caused the misbehaviour and how can I resolve this?

答案1

得分: 1

你可以如下修改ViewB的代码:

struct ViewB: View {
    let items: [Item] = [
        Item(title: "项目1", description: "这是项目1"),
        Item(title: "项目2", description: "这是项目2")
    ]
    
    var body: some View {
        List(items) { item in
            NavigationLink {
                ViewC(item: item)
            } label: {
                Text(item.title)
            }
        }
    }
}

SwiftUI NavigationStack: 列表视图导航行为意外
```

英文:

You can modify the code of ViewB as follows:

struct ViewB: View {
    let items: [Item] = [
        Item(title: "Item 1", description: "This is item 1"),
        Item(title: "Item 2", description: "This is item 2")
    ]
    
    var body: some View {
        List(items) { item in
            NavigationLink {
                ViewC(item: item)
            } label: {
                Text(item.title)
            }
        }
    }
}

<img src="https://i.stack.imgur.com/mfFtZ.gif" width="200" />

huangapple
  • 本文由 发表于 2023年6月1日 10:01:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76378239.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定