TableViewController.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2014 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. import UIKit
  19. import RealmSwift
  20. #if !swift(>=4.2)
  21. extension UITableViewCell {
  22. typealias CellStyle = UITableViewCellStyle
  23. typealias EditingStyle = UITableViewCellEditingStyle
  24. }
  25. #endif
  26. class DemoObject: Object {
  27. @objc dynamic var title = ""
  28. @objc dynamic var date = NSDate()
  29. @objc dynamic var sectionTitle = ""
  30. }
  31. class Cell: UITableViewCell {
  32. override init(style: UITableViewCell.CellStyle, reuseIdentifier: String!) {
  33. super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
  34. }
  35. required init(coder: NSCoder) {
  36. fatalError("NSCoding not supported")
  37. }
  38. }
  39. var sectionTitles = ["A", "B", "C"]
  40. var objectsBySection = [Results<DemoObject>]()
  41. class TableViewController: UITableViewController {
  42. var notificationToken: NotificationToken?
  43. var realm: Realm!
  44. override func viewDidLoad() {
  45. super.viewDidLoad()
  46. setupUI()
  47. realm = try! Realm()
  48. // Set realm notification block
  49. notificationToken = realm.observe { [unowned self] _, _ in
  50. self.tableView.reloadData()
  51. }
  52. for section in sectionTitles {
  53. let unsortedObjects = realm.objects(DemoObject.self).filter("sectionTitle == '\(section)'")
  54. let sortedObjects = unsortedObjects.sorted(byKeyPath: "date", ascending: true)
  55. objectsBySection.append(sortedObjects)
  56. }
  57. tableView.reloadData()
  58. }
  59. // UI
  60. func setupUI() {
  61. tableView.register(Cell.self, forCellReuseIdentifier: "cell")
  62. self.title = "GroupedTableView"
  63. self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "BG Add", style: .plain, target: self, action: #selector(TableViewController.backgroundAdd))
  64. self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(TableViewController.add))
  65. }
  66. // Table view data source
  67. override func numberOfSections(in tableView: UITableView) -> Int {
  68. return sectionTitles.count
  69. }
  70. override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
  71. return sectionTitles[section]
  72. }
  73. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  74. return objectsBySection[section].count
  75. }
  76. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  77. let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell
  78. let object = objectForIndexPath(indexPath: indexPath)
  79. cell.textLabel?.text = object?.title
  80. cell.detailTextLabel?.text = object?.date.description
  81. return cell
  82. }
  83. override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
  84. if editingStyle == .delete {
  85. try! realm.write {
  86. realm.delete(objectForIndexPath(indexPath: indexPath)!)
  87. }
  88. }
  89. }
  90. // Actions
  91. @objc func backgroundAdd() {
  92. // Import many items in a background thread
  93. DispatchQueue.global().async {
  94. // Get new realm and table since we are in a new thread
  95. autoreleasepool {
  96. let realm = try! Realm()
  97. realm.beginWrite()
  98. for _ in 0..<5 {
  99. // Add row via dictionary. Order is ignored.
  100. realm.create(DemoObject.self, value: ["title": randomTitle(), "date": NSDate(), "sectionTitle": randomSectionTitle()])
  101. }
  102. try! realm.commitWrite()
  103. }
  104. }
  105. }
  106. @objc func add() {
  107. try! realm.write {
  108. realm.create(DemoObject.self, value: [randomTitle(), NSDate(), randomSectionTitle()])
  109. }
  110. }
  111. }
  112. // Helpers
  113. func objectForIndexPath(indexPath: IndexPath) -> DemoObject? {
  114. return objectsBySection[indexPath.section][indexPath.row]
  115. }
  116. func randomTitle() -> String {
  117. return "Title \(arc4random())"
  118. }
  119. func randomSectionTitle() -> String {
  120. return sectionTitles[Int(arc4random()) % sectionTitles.count]
  121. }