Vollbildansicht der Tabellenansicht Nur-iPad-App. Ich habe Swipe zum Löschen auf meinen Zeilen aktiviert. Die Zeilenanimation endet immer nach dem Löschen (commitEditingStyle wird abgeschlossen), aber gelegentlich wird die gesamte Tabellenansicht eingefroren. Nicht die ganze Benutzeroberfläche, wohlgemerkt, es ist kein blockierter Haupt-Thread. Ich kann auf eine Spaltenüberschrift tippen oder auf die Zurück-Schaltfläche auf dem Navigationscontroller tippen, aber die Tabelle selbst wird gesperrt und kann nicht kopiert werden. Ich kann es einfach auftauen, indem ich auf eine meiner Spaltenkopf-Schaltflächen tippe.UITableView friert nach dem Wischen ein, um die gesamte Benutzeroberfläche zu löschen.
Ich bin nur völlig ratlos, was könnte das Einfrieren verursachen. Ich verwende einen NSFetchedResultsController und hier ist mein Delegate-Code dafür. Es ist ziemlich Kesselblech (aktualisiert: nicht als Kesselplatte jetzt einen batching Ansatz verwenden.):
// MARK: NSFetchedResultsController delegate methods
lazy var deletedSectionIndexes : NSMutableIndexSet = {
return NSMutableIndexSet()
}()
lazy var insertedSectionIndexes : NSMutableIndexSet = {
return NSMutableIndexSet()
}()
lazy var deletedRowIndexPaths : [NSIndexPath] = {
return [NSIndexPath]()
}()
lazy var insertedRowIndexPaths : [NSIndexPath] = {
return [NSIndexPath]()
}()
lazy var updatedRowIndexPaths : [NSIndexPath] = {
return [NSIndexPath]()
}()
func controllerWillChangeContent(controller: NSFetchedResultsController) {
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch(type) {
case .Delete:
if let indexPath = indexPath {
self.deletedRowIndexPaths.appendDistinct(indexPath)
}
case .Update:
if let indexPath = indexPath {
self.updatedRowIndexPaths.appendDistinct(indexPath)
}
case .Insert:
if let newIndexPath = newIndexPath {
self.insertedRowIndexPaths.appendDistinct(newIndexPath)
}
case .Move:
if let indexPath = indexPath, newIndexPath = newIndexPath {
self.insertedRowIndexPaths.appendDistinct(newIndexPath)
self.deletedRowIndexPaths.appendDistinct(indexPath)
}
}
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch(type) {
case .Delete:
self.deletedSectionIndexes.addIndex(sectionIndex)
case .Insert:
self.insertedSectionIndexes.addIndex(sectionIndex)
default:
break
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
self.tableView.insertSections(self.insertedSectionIndexes, withRowAnimation: .None)
self.tableView.deleteSections(self.deletedSectionIndexes, withRowAnimation: .None)
self.tableView.insertRowsAtIndexPaths(self.insertedRowIndexPaths, withRowAnimation: .None)
self.tableView.deleteRowsAtIndexPaths(self.deletedRowIndexPaths, withRowAnimation: .None)
self.tableView.reloadRowsAtIndexPaths(self.updatedRowIndexPaths, withRowAnimation: .None)
self.tableView.endUpdates()
self.insertedSectionIndexes.removeAllIndexes()
self.deletedSectionIndexes.removeAllIndexes()
self.deletedRowIndexPaths.removeAll()
self.insertedRowIndexPaths.removeAll()
self.updatedRowIndexPaths.removeAll()
}
Der Lösch im didChangeObject Delegatmethode aufgerufen wird, aber technisch ist es nicht ein echte löschen. Ich setze einfach eine Eigenschaft auf -1 und speichere dann dieses Element durch den NSMangagedObjectContext - an diesem Punkt scheint die NSFRC das Richtige zu tun, was sie aus der Liste der abgerufenen Objekte entfernt, die mit diesem Prädikat abgerufen wurden:
NSPredicate(format: "account = %@ and quantity != -1", account)
Dabei ist account
ein gültiges kontoverwaltetes Objekt. Die Zeile verschwindet ohne ein Problem 90% oder mehr der Zeit. Es ist nur gelegentlich, dass nach dem Abschluss der Animation der Tisch in dem von mir beschriebenen Herrenhaus zufriert. Es friert niemals ein, wenn die Lösch-Schaltfläche noch angezeigt wird, also weiß ich, dass es nach dem Aufruf von commitEditingStyle aufgerufen wird. Die Schaltfläche Löschen verfügt nicht über eine benutzerdefinierte Implementierung. Dies ist die standardmäßige UITableView-Implementierung von Swipe zum Löschen. Hier ist meine commitEditingStyle Methode:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
if let frameboardItem = self.fetchedResultsController.objectAtIndexPath(indexPath) as? IRMFrameBoardItemMO {
if frameboardItem.isNew {
// If it's never been pushed to the server, just delete locally. This will trigger a table reload
// via NSFetchedResultsController
DataManager.mainContext.deleteObject(frameboardItem)
} else {
// Otherwise mark it with a negative quantity which tells the server to delete it and tells the
// app to hide it.
frameboardItem.quantity = -1
}
do {
try DataManager.mainContext.save()
} catch let error as NSError {
dLog("Something went wrong: \(error.localizedDescription)")
}
}
}
}
Sie ein Video sehen kann hier von dem, was ich rede. Es ist über zwei Minuten, also wollen Sie vielleicht nicht die ganze Sache sehen, aber ich werde es hier als Referenz setzen.
Würde gerne Vorschläge hören.
aktualisieren
ich die NSFRC Delegatmethoden aktualisiert, um eine Dosierung Ansatz zu verwenden, um die Updates, um sicherzustellen, erhalten alle auf einmal angewendet. Dies hat das Problem nicht behoben. Der Tisch friert immer noch periodisch ein.
Sind Sie sicher, dass die Datenquelle ordnungsgemäß aktualisiert wird? Gibt es eine Situation, in der 'frameboardItem' in der folgenden Anweisung' nil' ist: 'wenn frameboardItem = self.fetchedResultsController.objectAtIndexPath (indexPath) als? IRMFrameBoardItemMO'? Und wenn es "Null" ist, wird die Tabelle aktualisiert, ohne dass die Datenquelle aktualisiert wird? – Alexander
Ich habe mir das Video mehrmals angesehen, wo du gelöscht hast und es war eiskalt. Es scheint zu tun, wenn Sie oben und unten von einem Abschnitt löschen und dann Abschnitte ändern. und lösche oben und unten. Oder vielleicht sind es nur ein oder zwei bestimmte Abschnitte. Ich frage mich, ob es ein Problem mit der Anzahl Ihrer Listen gibt oder wie diese Objekte neu positioniert werden. das hält die UI der Tabelle hoch. Es wäre gut, wenn Sie es eingrenzen könnten, wie genau es reproduzierbar ist. Ich denke nur laut nach. –
1) Ist das TableView in einem untergeordneten Ansichtscontroller? 2) Wenn Sie zu Testzwecken eine der Tasten (die auf Berührungen reagieren) so ändern, dass der Fernseher nach oben (oder unten) blättert, scrollt er tatsächlich? Das könnte einen Hinweis darauf geben, ob der Fernseher Berührungen ignoriert oder ob er friert, wenn er versucht zu scrollen. – pbasdf