【问题标题】:Deleting Row from UISearchResults filtered list using Realm使用 Realm 从 UISearchResults 过滤列表中删除行
【发布时间】:2015-12-28 17:47:37
【问题描述】:

我使用 Realm 作为我的后端数据存储,并且我有一个带有 UISearchResults 控制器的 tableview。 如果我不过滤结果,我可以从 tableView 中删除一行并将其从我的 Realm 数据库中删除。 但是,当我使用 SearchController 过滤并尝试滑动删除该行时,我得到了错误。

原因:'无效更新:第 0 节中的行数无效。 更新后现有部分中包含的行数 (2) 必须等于该节之前包含的行数 更新(2),加上或减去插入或删除的行数 从该部分(0 插入,1 删除)和加号或减号 移入或移出该部分的行数(0 移入,0 移出)。'

这是我在过滤位置时使用的函数

func filterContentForSearchText(searchText: String, scope: String = "All") {
        filteredLocations  = locations.filter { location in
            return location.site.lowercaseString.containsString(searchText.lowercaseString)
        }
        tableView.reloadData()
    }

这是我的 tableView 删除功能

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == UITableViewCellEditingStyle.Delete {
            if searchController.active && searchController.searchBar.text != "" {
                // This is from a filtered list
                do {
                    try realm.write() {
                        self.realm.delete(filteredLocations[indexPath.row])
                    }
                   tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)

                } catch {
                    print("Could not delete site")
                }
            } else {
                do {
                    try realm.write() {
                        self.realm.delete(locations[indexPath.row])
                    }
                    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
                } catch {
                    print("Could not delete site")
                }
            }
        }
    }

谁能帮我解决这个问题?

【问题讨论】:

    标签: swift uitableview realm uisearchcontroller


    【解决方案1】:

    我在这个问题上苦苦挣扎了很长时间。自从提出这个问题以来已经有一段时间了,但是对于未来的人来说,这可能会有所帮助。我不知道 Realm,但对于那些使用 Core Data 的人,我发现我需要做的就是在 fetchedResultsController didChangeObject 方法中重新加载 tableview 以进行删除和更新。

    例如:

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
        switch type {
            case .Insert:
                tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
            case .Delete:
    
                if searchController.active && searchController.searchBar.text != "" {
                    tableView.reloadData()//THIS
                } else {
                    tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
                }//if else
    
            case .Update:
    
                if searchController.active && searchController.searchBar.text != "" {
                    tableView.reloadData()//AND THIS
                } else {
                    self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)
                }//if else
    
            case .Move:
                tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
                tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
        }
    }//controller:didChangeObject
    

    【讨论】:

      【解决方案2】:

      如果您尝试删除单元格而不首先从数据源中完全删除等效对象,则会在UITableView 中出现该错误消息。错误消息是 section after the update (2) 而不是 (1) 的事实似乎意味着您的数据源仍然挂在对您刚刚从 Realm 中删除的项目的引用。

      从外观上看,由于您是自己手动生成 filteredObjects 的内容,因此您可能还需要手动删除其中的条目,在您从 Realm 中删除它之后,但在您之前调用UITableView单元格删除方法。

      if searchController.active && searchController.searchBar.text != "" {
          // This is from a filtered list
          do {
              try realm.write() {
                  self.realm.delete(filteredLocations[indexPath.row])
              }
              filteredLocations.removeAtIndex(indexPath.row)
              tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
          } catch {
              print("Could not delete site")
          }
      }
      

      我猜它工作正常,因为locations 很可能是来自 Realm 的 Results 对象,它会在您指示 Realm 删除它后自动更新以删除该项目。

      【讨论】:

        【解决方案3】:

        我有同样的问题,这个问题实际上与 Realm 对象删除无关。这与删除对象后 tableview 行数不同有关。我能够对搜索控制器进行 if 检查并确定是否需要运行 .deleteRowsAtIndexPaths。这修复了我的崩溃,但搜索结果不会更新以反映已删除的对象。它只会挂起。调用 .searchResultsUpdater 解决了这个问题。不确定它是否会有所帮助,但我的应用程序的代码如下。请注意,我使用辅助类来执行我的所有 Realm 功能,并且在删除行后重新加载我的数据源数组。

            func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
            if editingStyle == .Delete {
        
                var studentToDelete = Student()
        
                if searchController.active && searchController.searchBar.text != ""{
                    studentToDelete = filteredStudents[indexPath.row]
                    DBhelper.deleteByName(studentToDelete.name)
                    students = DBhelper.getAllObjetcs()
                    searchController.searchResultsUpdater?.updateSearchResultsForSearchController(searchController)
        
                }else{
                    studentToDelete = students[indexPath.row]
                    DBhelper.deleteByName(studentToDelete.name)
                    students = DBhelper.getAllObjetcs()
                    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
                }
        
        
            } else if editingStyle == .Insert {
                // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2018-07-27
          • 2014-06-29
          • 1970-01-01
          • 2010-09-20
          • 2016-09-30
          • 2017-08-12
          • 1970-01-01
          • 2020-08-31
          • 2013-04-22
          相关资源
          最近更新 更多