Swiftui 基于条件显示NavigationLink并在目标内编辑值

Swiftui 基于条件显示NavigationLink并在目标内编辑值,swiftui,Swiftui,我的StudentStore有一个ForEach循环,只有当isFavorite字段为true时,我才想在列表中显示它们 问题是,当我在SecondView中编辑isFavorite的值时,由于ContentView中的if语句,它会返回到ContentView 我希望列表在返回到ContentView时更新,而不是立即更新,使其返回到原始页面 当我在寻找解决方案时,我发现: 阅读整个帖子时,你会想,你是否可以有条件地隐藏NavigationView,然后会想,“听起来像一团糟……” 资料来源

我的
StudentStore
有一个ForEach循环,只有当
isFavorite
字段为true时,我才想在列表中显示它们

问题是,当我在
SecondView
中编辑isFavorite的值时,由于
ContentView
中的
if
语句,它会返回到
ContentView

我希望列表在返回到
ContentView
时更新,而不是立即更新,使其返回到原始页面

当我在寻找解决方案时,我发现:

阅读整个帖子时,你会想,你是否可以有条件地隐藏NavigationView,然后会想,“听起来像一团糟……”
资料来源:

有人能告诉我如何解决这个问题吗?为什么有条件地隐藏
导航视图是个坏主意

模型

主视图

struct ContentView: View {
    @ObservedObject var studentStore = StudentStore(StudentStore: [StudentItem(name: "Stephen", isFavorite: true),
                                                                   StudentItem(name: "Jay", isFavorite: true),
                                                                   StudentItem(name: "Isaac", isFavorite: true),
                                                                   StudentItem(name: "Talha", isFavorite: true),
                                                                   StudentItem(name: "John", isFavorite: true),
                                                                   StudentItem(name: "Matt", isFavorite: true),
                                                                   StudentItem(name: "Leo", isFavorite: true)])

    var body: some View {
        NavigationView {
            List {
                ForEach(studentStore.StudentStore.indices, id: \.self) { index in
                    Group {
                        if self.studentStore.StudentStore[index].isFavorite == true {
                            NavigationLink(destination: SecondView(student: self.$studentStore.StudentStore[index])) {
                                HStack {
                                    Text(self.studentStore.StudentStore[index].name)
                                    Image(systemName: self.studentStore.StudentStore[index].isFavorite ? "star.fill" : "star")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
子视图

struct SecondView: View {
    @Binding var student: StudentItem

    var body: some View {
        Button(action: {
            self.student.isFavorite.toggle()
        }) {
            Image(systemName: student.isFavorite ? "star.fill" : "star")
        }
    }
}

这个问题是有道理的,它是一个绑定值。根据绑定,从技术上讲,指向此人的导航
SecondView
不再存在

您可以为
SecondView
创建本地化的
状态
,将图像和按钮设置为使用该属性,然后在返回时使用
onDisappear
更新
StudentItem

struct SecondView: View {
    @Binding var student: StudentItem
    @State var isFavorite: Bool = true

    var body: some View {
        Button(action: {
            self.isFavorite.toggle()
        }) {
            Image(systemName: self.isFavorite ? "star.fill" : "star")
        }.onDisappear {
            self.student.isFavorite = self.isFavorite
        }
    }
}
以上内容将与您的其余代码一起使用

至于不使用
if
语句,我有点明白了。对我来说,我想迭代我知道我想要包含的值。并不是说这很完美,但您可以在进入之前过滤列表,然后调用对
StudentItem
的可绑定引用,以传递到
SecondView
。确保
StudentItem
可散列
以使其正常工作:

var body: some View {
        NavigationView {
            List {
                ForEach(studentStore.StudentStore.filter({$0.isFavorite == true}), id: \.self) { student in
                    Group {
                        NavigationLink(destination: SecondView(student: self.$studentStore.StudentStore[self.studentStore.StudentStore.firstIndex(of: student)!])) {
                                HStack {
                                    Text(student.name)
                                    Image(systemName: student.isFavorite ? "star.fill" : "star")
                                }
                            }
                        }
                }
            }
        }
    }

这会产生一个更理想的结果,但我更希望在
列表
可见之前进行转换。另一个解决方案是制作自己的后退按钮,类似于解决方案。通过这种方式,您可以在调用撤销之前专门更新可绑定对象。需要注意的是,我不确定在将值更新为false后是否仍要调用disclose,因为这可能会像根问题lol中那样“自动disclose”。
var body: some View {
        NavigationView {
            List {
                ForEach(studentStore.StudentStore.filter({$0.isFavorite == true}), id: \.self) { student in
                    Group {
                        NavigationLink(destination: SecondView(student: self.$studentStore.StudentStore[self.studentStore.StudentStore.firstIndex(of: student)!])) {
                                HStack {
                                    Text(student.name)
                                    Image(systemName: student.isFavorite ? "star.fill" : "star")
                                }
                            }
                        }
                }
            }
        }
    }