#swift #swiftui #observedobject
#swift #swiftui #observedobject
Вопрос:
У меня следующая модель данных:
class MyImage: : Identifiable, Equatable, ObservableObject {
let id = UUID()
var path: String
@Published var coordinate: CLLocationCoordinate2D?
}
class MyImageCollection : ObservableObject {
@Published var images: [MyImage] = []
@Published var selection: Set<UUID> = []
}
extension Array where Element == MyImage {
func haveCoordinates() -> Array<MyImage> {
return filter { (image) -> Bool in
return image.coordinate != nil
}
}
}
Я использую коллекцию в представлениях следующим образом:
# Top View
@StateObject var imageModel: MyImageCollection = MyImageCollection()
# Dependend Views
@ObservedObject var imageModel: MyImageCollection
Итак, в моем SwiftUI всякий раз, когда я добавляю новый экземпляр myImage через imageCollection.images.append(anImage)
, все работает отлично, и любое представление обновляется соответствующим образом, также обновляется любое представление, использующее imageCollection.haveCoordinates()
. Но я также хочу, чтобы любые представления обновлялись, когда я изменяю свойство изображения, например imageCollection.images[0].coordinate = someCoordinate
. В настоящее время это не работает.
Какие-либо подсказки?
Ответ №1:
Ваши подвиды должны непосредственно наблюдать за вашим классом ‘myImage’, который будет соответствующим образом обновлен. Передайте ваши экземпляры ‘myImage’ непосредственно в наблюдаемую объектную переменную. Вот как это может выглядеть…
ForEach(collection.images) { myImage in
YourSubView(image: myImage)
}
Где параметр изображения передается наблюдаемому свойству объекта в вашем подвиде.
Ответ №2:
Переключите @ObservedObject
@EnvironmentObject
на DependantView
и инициализируйте DependentView().environmentObject(imageModel)
. Документация Apple.Это соединяет два экземпляра.
Кроме того, если вы хотите наблюдать за каждым MyImage
, вам нужно создать MyImageView
объект, который наблюдает за ним напрямую
struct MyImage: View{
@ObservedObject var myImage: MyImage
//Rest of code
}
Ответ №3:
Спасибо за ваши ответы, очень признателен. Я пытался создать вложенное представление со ссылкой на объект также как ObservableObject, но потерпел неудачу, потому что я использовал MapAnnotation
и инициализировал coordinate
свойство. Нужно подробно разобраться, в чем здесь разница, документация от Apple не очень помогает сразу увидеть какую-либо разницу. Сейчас я использую какой-то обходной путь, «аннулируя» экземпляр myImage с установкой нового UUID:
class MyImage: : Identifiable, Equatable, ObservableObject {
var id = UUID()
var path: String
@Published var coordinate: CLLocationCoordinate2D? {
didSet {
id = UUID()
}
}
}