我使用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")
}
}
}
}
有人可以帮我解决这个问题吗?
答案 0 :(得分: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
答案 1 :(得分:0)
如果您尝试删除单元格而不首先从数据源中完全删除等效对象,则会在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删除它后自动更新自己以删除该项目。 / p>
答案 2 :(得分:0)
我有同样的问题,问题实际上与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
}
}