1
我使用帶有Realm結果的UITableView作爲數據源。結果通過領域通知進行註冊,並在發生更改時進行更新。但是,同一個表視圖具有一個搜索欄,可根據用戶搜索查詢過濾結果。這也可以正常工作,但是如果通知偵聽器識別出更新,則部分和行計數不匹配。什麼是正確的方法來做到這一點?是否可以更新NotificationToken?如果在通知初始化後更新結果,我如何使用領域通知?
這是初始化通知令牌的代碼:
let realm = try! Realm()
results = realm.objects(Person.self).filter("active = '1'").sorted(byProperty: "name", ascending: true)
// Observe Results Notifications
notificationToken = results?.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
guard let tableView = self?.tableView else { return }
switch changes {
case .initial:
// Results are now populated and can be accessed without blocking the UI
tableView.reloadData()
break
case .update(_, let deletions, let insertions, let modifications):
// Query results have changed, so apply them to the UITableView
tableView.beginUpdates()
tableView.insertRows(at: insertions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
tableView.deleteRows(at: deletions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
tableView.reloadRows(at: modifications.map { IndexPath(row: $0, section: 0) }, with: .automatic)
tableView.endUpdates()
break
case .error(let error):
// An error occurred while opening the Realm file on the background worker thread
print("Error: \(error)")
break
}
}
此代碼更新基於用戶搜索輸入的結果:
func updateSearchResults(for searchController: UISearchController) {
let searchText = searchController.searchBar.text!
if searchText.isEmpty == false {
results = results?.realm?.objects(Person.self).filter("active = '1'")
results = results?.filter("name BEGINSWITH[c] %@ OR lastName CONTAINS[c] %@", searchText, searchText)
results = results?.sorted(byProperty: "name", ascending: true)
self.tableView.reloadData()
}
else {
results = results?.realm?.objects(Person.self).filter("active = '1'").sorted(byProperty: "name", ascending: true)
self.tableView.reloadData()
}
}
如果搜索qwuery已經執行和前面帶有對領域數據庫的更新,會發生NSRange異常。
優秀的,是有道理的。感謝您的好解決方案! – fisher
沒有想到通知令牌的行爲如此,謝謝澄清 –