Из сессий Apple и Tutorial у нас есть две опции для передачи BindableObject представлениям.
- Используйте объявление сотню
BindableObject
как источник истины в виде сверху в иерархии с @ObjectBinding
обернуть и передать его в другие представления с объявленным @Binding
. - Использовать объявить
BindableObject
в качестве источника истины в верхнем представлении в иерархии с оберткой @EnviromentObject
, начальном представлении сверху с модификатором .enviroment(BindableObject)
и передать его в другие представления либо с объявленным @Binding
, либо с использованием @EnviromentObject
(в этом случае SwiftUI будет автоматически назначать BindableObject
, и нам не нужно передавать его при инициализации).
Из Обучающее руководство по пользовательскому вводу если у нас есть BindableObject
со списком элементов и мы хотим изменить один из элементов в другом представлении (или RowView или даже отдельном экране), нам нужно:
- Передайте
BindableObject
в более глубокое представление любым из способов выше. - Передача выбранного элемента в это представление.
- Свяжите свойство элемента с помощью
BindingView
, найдя элемент в списке BindableObject
.
Некоторый код, чтобы прояснить вопрос:
Модель сообщения и BindableObject
struct Message: Identifiable {
var id: String
var toggle: Bool = true
}
class MessageStore: BindableObject {
let didChange = PassthroughSubject<MessageStore, Never>()
var messagesList: [Message] = testData {
didSet {
didChange.send(self)
}
}
}
MessageView, представляющий список элементов struct MessagesView
: View {
@EnvironmentObject var messageStore: MessageStore
var body: some View {
NavigationView {
List(messageStore.messagesList) { message in
NavigationButton(destination: Text(message.id)) {
MessageRow(message: message)
}
}
.navigationBarTitle(Text("Messages"))
}
}
}
MessageRowкоторый имеет переключатель для обновления состояния определенного элемента в BindableObject
struct MessageRow: View {
@EnvironmentObject var tags: MessageStore
var message: Message
var messageIndex: Int {
tags.messagesList.firstIndex { $0.id == message.id }!
}
var body: some View {
Toggle(isOn: self.$tags.messagesList[self.messageIndex].toggle) {
Text("Test toogle")
}
}
}
Этот подход показан в учебнике, о котором я упоминал выше.
Вопрос: Я хотел передать Message отдельно как @Binding
, чтобы напрямую работать с ним в дочернем представлении, но я не смог реализовать это.Я немного запутался.Является ли правильным способом перейти к любому представлению (которое должно обрабатывать привязки) как BindableObject
, так и выбранному элементу для последующей привязки элемента из BindableObject
с использованием индекса?Есть ли другой способ, который позволит пройти не полную BindableObject
, а ее часть и связать эту часть (это должен быть Источник истины), в нашем случае эта часть Message
?