SwiftUI 订阅 属性 更改为 EnvironmentObject
SwiftUI Subscribing to property change with EnvironmentObject
这是我的模型:
class Channel: Identifiable, Decodable, ObservableObject {
var id = UUID()
var channelId = ""
var title = ""
var thumbnail = ""
@Published var thumbnailImage : UIImage?
enum CodingKeys: String, CodingKey {
//Keys not in the model
case snippet
case thumbnails
case high
//Keys in the model
case channelId
case title
case thumbnail = "url"
}
required init (from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let snippetContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .snippet)
let thumbnailsContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .thumbnails)
let highContainer = try thumbnailsContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .high)
self.title = try snippetContainer.decode(String.self, forKey: .title)
self.thumbnail = try highContainer.decode(String.self, forKey: .thumbnail)
self.channelId = try snippetContainer.decode(String.self, forKey: .channelId)
}
}
class ChannelStore: ObservableObject {
@Published var allChannels = [Channel]()
}
我有一个链接到 ChannelStore 的 EnvironmentObject,它都按预期工作。
问题是 属性 thumbnailImage 更改时我的视图需要更新。 (由于它来自网络调用,视图在调用 returns 之前生成,同时使用库存图像)。我尝试将 Published 属性 包装器添加到那个 属性 但它没有做任何事情。
在我看来我有:@EnvironmentObject var channelStore: ChannelStore
如何订阅由 EnvironmentObject 管理的 属性 变更?
编辑
建议将通道 class 更改为结构。我制作 class 的唯一原因是为了避免“无法分配给 属性:'channel' 是一个 'let' 常量:
for channel in channelStore.allChannels {
networking.setThumbnail(channel: channel) { image in
channel.thumbnailImage = image
}
}
最终评论
我能够使用下面提供的答案解决整个问题,并将我的 for 循环更改为以下内容:
for (index, var channel) in channelStore.allChannels.enumerated() {
networking.setThumbnail(channel: channel) { image in
channel.thumbnailImage = image
channelStore.allChannels[index] = channel
print("Images LOADED")
}
}
如果你能让你的 Channel
成为一个 struct:
struct Channel: Identifiable, Decodable { // <- replace `class` with `struct`
...
var thumbnailImage : UIImage? // <- remove `@Published`
}
然后 thumbnailImage
的每次修改都会创建 Channel
对象的新副本并触发 ChannelStore
中的 @Published
属性:
class ChannelStore: ObservableObject {
@Published var allChannels = [Channel]()
}
这是我的模型:
class Channel: Identifiable, Decodable, ObservableObject {
var id = UUID()
var channelId = ""
var title = ""
var thumbnail = ""
@Published var thumbnailImage : UIImage?
enum CodingKeys: String, CodingKey {
//Keys not in the model
case snippet
case thumbnails
case high
//Keys in the model
case channelId
case title
case thumbnail = "url"
}
required init (from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let snippetContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .snippet)
let thumbnailsContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .thumbnails)
let highContainer = try thumbnailsContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .high)
self.title = try snippetContainer.decode(String.self, forKey: .title)
self.thumbnail = try highContainer.decode(String.self, forKey: .thumbnail)
self.channelId = try snippetContainer.decode(String.self, forKey: .channelId)
}
}
class ChannelStore: ObservableObject {
@Published var allChannels = [Channel]()
}
我有一个链接到 ChannelStore 的 EnvironmentObject,它都按预期工作。
问题是 属性 thumbnailImage 更改时我的视图需要更新。 (由于它来自网络调用,视图在调用 returns 之前生成,同时使用库存图像)。我尝试将 Published 属性 包装器添加到那个 属性 但它没有做任何事情。
在我看来我有:@EnvironmentObject var channelStore: ChannelStore
如何订阅由 EnvironmentObject 管理的 属性 变更?
编辑
建议将通道 class 更改为结构。我制作 class 的唯一原因是为了避免“无法分配给 属性:'channel' 是一个 'let' 常量:
for channel in channelStore.allChannels {
networking.setThumbnail(channel: channel) { image in
channel.thumbnailImage = image
}
}
最终评论
我能够使用下面提供的答案解决整个问题,并将我的 for 循环更改为以下内容:
for (index, var channel) in channelStore.allChannels.enumerated() {
networking.setThumbnail(channel: channel) { image in
channel.thumbnailImage = image
channelStore.allChannels[index] = channel
print("Images LOADED")
}
}
如果你能让你的 Channel
成为一个 struct:
struct Channel: Identifiable, Decodable { // <- replace `class` with `struct`
...
var thumbnailImage : UIImage? // <- remove `@Published`
}
然后 thumbnailImage
的每次修改都会创建 Channel
对象的新副本并触发 ChannelStore
中的 @Published
属性:
class ChannelStore: ObservableObject {
@Published var allChannels = [Channel]()
}