Показывать NavigationLink в зависимости от условия и изменения значения в пункте назначения - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть ForEach l oop для моих StudentStore, и я хочу отображать их в своем списке, только если поле isFavorite установлено в true.

Проблема в том, что когда я редактирую значение isFavorite внутри SecondView, оно возвращается к ContentView из-за оператора if внутри ContentView.

Мне нужен список обновить, когда я вернусь к ContentView, а не обновлю его немедленно, заставив его go вернуться на исходную страницу.

enter image description here

Когда я искал решение, на которое я наткнулся:

Прочитайте весь этот поток, думая, что вы спрашиваете, можете ли вы сделать NavigationView условно скрытым, и подумайте: «Это звучит как беспорядок ...»
Источник: https://www.reddit.com/r/SwiftUI/comments/e2wn09/make_navigationlink_conditional_based_on_bool/

Может кто-нибудь также как решить эту проблему и почему условное сокрытие NavigationView - плохая идея?

Модель

import SwiftUI

struct StudentItem: Identifiable {
    var id = UUID()
    var name: String
    var isFavorite: Bool

    init(name: String, isFavorite: Bool) {
        self.name = name
        self.isFavorite = isFavorite
    }
}

class StudentStore: ObservableObject {
    @Published var StudentStore: [StudentItem]

    init(StudentStore: [StudentItem]){
        self.StudentStore = StudentStore
    }
}

Основной вид

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")
        }
    }
}

1 Ответ

1 голос
/ 08 апреля 2020

Проблема имеет смысл, это значение Binded. Навигация к этому человеку SecondView технически больше не существует в соответствии с привязкой.

Вы можете создать локализованный State для 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, Я вроде понял. Для меня я бы хотел перебрать значения, которые я хочу включить. Не сказать, что это идеально, но вы могли бы отфильтровать список перед тем, как войти в go, а затем вызвать ссылку Bindable на StudentItem, чтобы перейти к SecondView. Обязательно наберите StudentItem Hashable, чтобы это работало:

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")
                                }
                            }
                        }
                }
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...