为什么在嵌入式 tableView 中显示 Realm 数据并不容易?
Why displaying Realm data in and embedded tableView does not come easy?
无法在 table 视图中显示来自 Realm 的数据,嵌入在视图控制器中。这是一些代码。
处理数据存储方式的数据模型class(这是一个财务跟踪应用程序):
class Entry: Object {
@objc dynamic var name: String = ""
@objc dynamic var amount: Int = 0
@objc dynamic var date: Date?
var isExpense: Bool = false
// initialization block dropped for concise post purposes
}
单元格class:
class FinanceOverviewCell: UITableViewCell {
@IBOutlet weak var entryNameLabel: UILabel!
@IBOutlet weak var entryAmountLabel: UILabel!
func updateData(name: String, amount: String) {
entryNameLabel?.text = name
entryAmountLabel?.text = amount
}
}
最后,视图控制器:
import UIKit
import RealmSwift
class FinanceOverviewController: UIViewController {
@IBOutlet weak var financeOverviewTableView: UITableView!
@IBOutlet weak var currentBalanceLabel: UILabel!
var realm = try! Realm()
let tableEntries = try! Realm().objects(Entry.self)
let entriesManager = EntriesManager()
var notificationToken: NotificationToken?
override func viewDidLoad() {
super.viewDidLoad()
print(tableEntries)
self.financeOverviewTableView.reloadData()
financeOverviewTableView.delegate = self
financeOverviewTableView.dataSource = self
// notification token code block dropped for concise post purposes
// outlets code block removed for concise post purposes
extension FinanceOverviewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
realm.beginWrite()
realm.delete(tableEntries[indexPath.row])
try! realm.commitWrite()
}
}
}
extension FinanceOverviewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableEntries.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = financeOverviewTableView.dequeueReusableCell(withIdentifier: "FinanceOverviewCell", for: indexPath) as! FinanceOverviewCell
let tableData = tableEntries[indexPath.row]
cell.updateData(name: tableData.name, amount: String(tableData.amount))
return cell
}
}
问题出在视图控制器的 cellForRowAt 函数中。不知何故,虽然 tableData 每次都包含一些适合添加行的内容,但它什么也没有添加。在应用程序屏幕中,我看到又一行带有占位符标签。
可能是什么问题?我阅读了一些参考资料并浏览了 official example,但没有看到针对这种情况的任何特殊解决方案。
感谢支持
实际上使用 Realm 并不难,我尝试重现您的代码并且一切正常。我认为这与 NotificationToken 有关,因为每次您的集合更改时,通知令牌 运行 代码块而且我不知道您如何更新您的 tableView。我建议你使用这个扩展,我已经用了好几个月了,这是采用 UITableView 和 Realm 的 NotificationToken 的最佳方式:
extension UITableView {
func applyChanges<T>(changes: RealmCollectionChange<T>) {
switch changes {
case .initial: reloadData()
case .update(let results, let deletions, let insertions, let updates):
let fromRow = { (row: Int) in return IndexPath(row: row, section: 0) }
beginUpdates()
insertRows(at: insertions.map(fromRow), with: .automatic)
reloadRows(at: updates.map(fromRow), with: .automatic)
deleteRows(at: deletions.map(fromRow), with: .automatic)
endUpdates()
case .error(let error): fatalError("\(error)")
}
}
}
用法示例:
notificationToken = tableEntries.addNotificationBlock { changes in
financeOverviewTableView.applyChanges(changes)
}
来源:https://academy.realm.io/posts/meetup-jp-simard-mastering-realm-notifications/
无法在 table 视图中显示来自 Realm 的数据,嵌入在视图控制器中。这是一些代码。
处理数据存储方式的数据模型class(这是一个财务跟踪应用程序):
class Entry: Object {
@objc dynamic var name: String = ""
@objc dynamic var amount: Int = 0
@objc dynamic var date: Date?
var isExpense: Bool = false
// initialization block dropped for concise post purposes
}
单元格class:
class FinanceOverviewCell: UITableViewCell {
@IBOutlet weak var entryNameLabel: UILabel!
@IBOutlet weak var entryAmountLabel: UILabel!
func updateData(name: String, amount: String) {
entryNameLabel?.text = name
entryAmountLabel?.text = amount
}
}
最后,视图控制器:
import UIKit
import RealmSwift
class FinanceOverviewController: UIViewController {
@IBOutlet weak var financeOverviewTableView: UITableView!
@IBOutlet weak var currentBalanceLabel: UILabel!
var realm = try! Realm()
let tableEntries = try! Realm().objects(Entry.self)
let entriesManager = EntriesManager()
var notificationToken: NotificationToken?
override func viewDidLoad() {
super.viewDidLoad()
print(tableEntries)
self.financeOverviewTableView.reloadData()
financeOverviewTableView.delegate = self
financeOverviewTableView.dataSource = self
// notification token code block dropped for concise post purposes
// outlets code block removed for concise post purposes
extension FinanceOverviewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
realm.beginWrite()
realm.delete(tableEntries[indexPath.row])
try! realm.commitWrite()
}
}
}
extension FinanceOverviewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableEntries.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = financeOverviewTableView.dequeueReusableCell(withIdentifier: "FinanceOverviewCell", for: indexPath) as! FinanceOverviewCell
let tableData = tableEntries[indexPath.row]
cell.updateData(name: tableData.name, amount: String(tableData.amount))
return cell
}
}
问题出在视图控制器的 cellForRowAt 函数中。不知何故,虽然 tableData 每次都包含一些适合添加行的内容,但它什么也没有添加。在应用程序屏幕中,我看到又一行带有占位符标签。
可能是什么问题?我阅读了一些参考资料并浏览了 official example,但没有看到针对这种情况的任何特殊解决方案。
感谢支持
实际上使用 Realm 并不难,我尝试重现您的代码并且一切正常。我认为这与 NotificationToken 有关,因为每次您的集合更改时,通知令牌 运行 代码块而且我不知道您如何更新您的 tableView。我建议你使用这个扩展,我已经用了好几个月了,这是采用 UITableView 和 Realm 的 NotificationToken 的最佳方式:
extension UITableView {
func applyChanges<T>(changes: RealmCollectionChange<T>) {
switch changes {
case .initial: reloadData()
case .update(let results, let deletions, let insertions, let updates):
let fromRow = { (row: Int) in return IndexPath(row: row, section: 0) }
beginUpdates()
insertRows(at: insertions.map(fromRow), with: .automatic)
reloadRows(at: updates.map(fromRow), with: .automatic)
deleteRows(at: deletions.map(fromRow), with: .automatic)
endUpdates()
case .error(let error): fatalError("\(error)")
}
}
}
用法示例:
notificationToken = tableEntries.addNotificationBlock { changes in
financeOverviewTableView.applyChanges(changes)
}
来源:https://academy.realm.io/posts/meetup-jp-simard-mastering-realm-notifications/