[英]What is the right way to present data from Realm in SwiftUI List
[英]How to delete data from SwiftUI List and Realm
以下代碼正確顯示 SwiftUI List
中Realm
數據庫中的所有“用戶”。 我的問題是滑動一行時刪除記錄。
當我滑動一行並點擊刪除按鈕時,我立即收到一個uncaught exception
錯誤, List
沒有更新,但我知道正確的項目已從Realm
數據庫中刪除,因為下次我運行應用程序時,所選記錄不會出現。
這是我的代碼。
import RealmSwift
struct ContentView: View {
@State private var allUsers: Results<User> = realm.objects(User.self)
var body: some View {
VStack{
Text("Second Tab")
List{
ForEach(allUsers, id:\.self) { user in
HStack{
Text(user.name)
Text("\(user.age)")
}
}.onDelete(perform: deleteRow)
}
}
}
private func deleteRow(with indexSet: IndexSet){
indexSet.forEach ({ index in
try! realm.write {
realm.delete(self.allUsers[index])
}
})
}
}
import RealmSwift
class User:Object{
@objc dynamic var name:String = ""
@objc dynamic var age:Int = 0
@objc dynamic var createdAt = NSDate()
@objc dynamic var userID = UUID().uuidString
override static func primaryKey() -> String? {
return "userID"
}
}
由於未捕獲的異常“RLMException”而終止應用程序,原因:“索引 4 超出范圍(必須小於 4)。”
當然,這4
項更改取決於Realm
數據庫中有多少項目,在這種情況下,當我滑動並點擊刪除按鈕時,我有 5 條記錄。
我的期望是每次allUsers
@State 變量更改時List
都會更新,我知道我的問題不是完全理解綁定是如何工作的。
我究竟做錯了什么?
我的期望是每次 allUsers @State 變量更改時列表都會更新
這是正確的,但 state 沒有改變......以下應該工作
private func deleteRow(with indexSet: IndexSet){
indexSet.forEach ({ index in
try! realm.write {
realm.delete(self.allUsers[index])
}
})
self.allUsers = realm.objects(User.self) // << refetch !!
}
注意:下面只是分配初始state 值
@State private var allUsers: Results<User> = realm.objects(User.self)
這是使用 Realm 時非常常見的錯誤。 它也發生在“傳統”視圖控制器中。
我發現的唯一可靠的解決方案,它顯着提高了應用程序的穩定性,是始終使用界面項而不是 realm object。
此外,在現實生活中,我們需要做一些處理,從服務器加載頭像圖像,添加一些復選框、選擇或其他任何東西,而且我們通常不需要顯示對象的所有屬性。 不知何故,這是一種 MVVM 方法。
順便說一句,你可以在循環之前調用realm.write
,不確定,但我認為最好減少上下文切換。
使用這種技術,無論是使用 SwiftUI 還是 UIViewControllers,都可以解決 RLM 崩潰問題。
struct ContentView: View {
struct UserItem: Hashable {
var id: String
var name: String
var age: Int
}
private var allUsers: Results<User> = realm.objects(User.self)
@State private var userItems: [UserItem] = []
func updateItems() {
userItems = allUsers.map {
UserItem(id: $0.userID, name: $0.name, age: $0.age)
}
}
var body: some View {
VStack {
Text("Second Tab")
List{
ForEach(userItems, id:\.self) { user in
HStack{
Text(user.name)
Text("\(user.age)")
}
}
.onDelete(perform: deleteRow)
}
}.onAppear() {
updateItems()
}
}
private func deleteRow(with indexSet: IndexSet){
try! realm.write {
indexSet.forEach {
realm.delete(self.allUsers[$0])
}
}
updateItems()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.