我一直在尝试弄清楚如何在SwiftUI中使用Realm。问题在于SwiftUI和Realm都具有List类型。当您将SwiftUI导入到Realm模型中以使该类成为BindableObject并尝试创建Realm List属性时,会出现错误。
是否可以使用Realm对象模型的实例,并使其在SwiftUI中成为BindableObject?
当然,这非常简单,使用模块标识符作为前缀,如下所示:
let members = RealmSwift.List<Member>()
Run Code Online (Sandbox Code Playgroud)
现在到您的问题的第二部分。将Realm对象(或列表或结果集)封装在中很容易BindableObject:
let members = RealmSwift.List<Member>()
Run Code Online (Sandbox Code Playgroud)
如果通过使用或DBData实例将实例“链接” 到SwiftUI View,则UI将会刷新,并且每次下层领域发生变化时(在我们的示例中)的新值将可用。@ObjectBinding@EnvironmentObjectposts
@JustinMiller 我创建了一个 ChannelsData 类,我用它来监听 Realm 集合中聊天频道的变化。然后我通过在我的视图中将 ChannelsData 设为 @EnvironmentObject 来更新 UI。这是在 Xcode 11 GM Seed 中对我有用的内容:
final class ChannelsData: ObservableObject {
@Published var channels: [Channel]
private var channelsToken: NotificationToken?
// Grab channels from Realm, and then activate a Realm token to listen for changes.
init() {
let realm = try! Realm()
channels = Array(realm.objects(Channel.self)) // Convert Realm results object to Array
activateChannelsToken()
}
private func activateChannelsToken() {
let realm = try! Realm()
let channels = realm.objects(Channel.self)
channelsToken = channels.observe { _ in
// When there is a change, replace the old channels array with a new one.
self.channels = Array(channels)
}
}
deinit {
channelsToken?.invalidate()
}
Run Code Online (Sandbox Code Playgroud)
然后我使用@EnvironmentObject 来获取频道以供查看:
struct ChannelsContainerView: View {
@EnvironmentObject var channelsData: ChannelsData
var body: some View {
List(channelsData.channels.indexed(), id: \.1.id) { index, _ in
NavigationLink(destination: ChatView()) {
ChannelRow(channel: self.$channelsData.channels[index])
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
不用担心 List 中的 indexed() 函数。但如果你好奇,它来自 Majid 在此处创建灵活的 SwiftUI 数据存储类的聪明方法:https ://mecid.github.io/2019/09/04/modeling-app-state-using-store-objects-在swiftui/
如果您从另一个视图进入视图,请务必将 .environmentObject(ChannelsData()) 添加到您的视图链接(以及您的预览中),否则它将无法工作。
| 归档时间: |
|
| 查看次数: |
1611 次 |
| 最近记录: |