Swiftui 迅捷导航不';更新结构时无法工作

Swiftui 迅捷导航不';更新结构时无法工作,swiftui,Swiftui,我有一个结构列表。点击按钮将调用结构上的变异函数,然后导航 但是导航不会触发。如果删除了对变异函数self.logins[index].updateLastLogin()的调用,它将重新开始工作。为什么? 要复制,请将以下内容粘贴到空的SwiftUI项目中: struct Login: Identifiable, Hashable { let id = UUID() let name: String var lastLogin: Date? mutating f

我有一个结构列表。点击按钮将调用结构上的变异函数,然后导航

但是导航不会触发。如果删除了对变异函数
self.logins[index].updateLastLogin()
的调用,它将重新开始工作。为什么?

要复制,请将以下内容粘贴到空的SwiftUI项目中:

struct Login: Identifiable, Hashable {
    let id = UUID()
    let name: String
    var lastLogin: Date?

    mutating func updateLastLogin() {
        self.lastLogin = Date()
    }
}

struct ContentView: View {
    @State private var logins = ["Zaphod", "Arthur", "Ford", "Marvin", "Trillian"].map { Login(name: $0) }
    @State private var selection: Login?

    var body: some View {
        NavigationView {
            List {
                ForEach(self.logins) { login in
                    VStack {
                        NavigationLink(destination: Text(login.name).font(.largeTitle),
                                       tag: login,
                                       selection: self.$selection) {
                            EmptyView()
                        }
                        Button(action: {
                            self.navigate(login: login)
                        }, label: {
                            Text(login.name)
                        })
                    }
                }
            }
        }
    }

    func navigate(login: Login) {
        guard let index = self.logins.firstIndex(of: login) else {
            fatalError()
        }

        self.logins[index].updateLastLogin() // remove this line
        self.selection = login
    }
}

下面是工作方法的演示。使用Xcode 12/iOS 14进行测试


选择
必须是
标记
(s)中的一个,然后激活相应的链接-这就是目的。@Asperi但即使将带有“updateLastLogin”的行作为导航函数的最后一行,它仍然不起作用。因为如果你说的话,我知道登录的哈希值改变了,因此标签不再相同。但是,如果在设置选择后调用了变异函数,我希望它能工作。我接受了答案,因为显然你付出了一些努力。我剩下的问题是:如果我在将结构分配给
selection
变量后对其进行了变异,为什么它不起作用?这正是因为selection是在修改后调用的,因为在修改后
logins
数组不包含任何更多的登录值(您的
struct login
是一个结构,而不是一个类),修改后的数组将重建列表,因为它是一个状态,所以列表包含带有新的更新标记的链接,但您将旧标记分配给选择,所以什么也不会发生。哦,是的。。。谢谢你的帮忙ᴗ•
struct DemoView: View {
    @State private var logins = ["Zaphod", "Arthur", "Ford", "Marvin", "Trillian"].map { Login(name: $0) }
    @State private var selection: UUID?

    var body: some View {
        NavigationView {
            List {
                ForEach(self.logins) { login in
                    VStack {
                        NavigationLink(destination: Text(login.name).font(.largeTitle),
                                       tag: login.id,
                                       selection: self.$selection) {
                            EmptyView()
                        }
                        Button(action: {
                            self.navigate(login: login)
                        }, label: {
                            Text(login.name)
                        })
                    }
                }
            }
        }
    }

    func navigate(login: Login) {
        guard let index = self.logins.firstIndex(of: login) else {
            fatalError()
        }

        self.logins[index].updateLastLogin() // remove this line
        self.selection = login.id
    }
}