2013-08-23 10 views
5

In meiner Anwendung, lade ich meine Tableview ([tablView reloadData];) nach Zeile löschen von Tableview dann canEditRowAtIndexPath Methode rufen alle Tage für (durchlässig) Gesamtanzahl der Zeilen.Bei canEditRowAtIndexPath-Methode funktionieren reloadData von UITableView nicht richtig?

Beispiel:

Wenn i Zeilen auf meinem Tableview haben, i Reihe von Tableview dann löschen. Nach dem Löschen ich meine Tableview ([tablView reloadData]) aber canEditRowAtIndexPath Methode ruft 5 Mal statt 4 mal nachladen ??

Ich habe also immer Fehler Folgende:

Terminating app due to uncaught exception 'NSRangeException', reason: '* **-[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]'

Ich habe auch versucht Tisch nach einer gewissen Verzögerung neu zu laden (mit NSTimer), aber es für mich auch nicht funktioniert.

habe ich einige Code hier:

I canEditRowAtIndexPath auf bestimmte Zeile anwenden, welche @"status" isEqualToString:@"directory" so wie,

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSLog(@"%d", self.listOfSounds.count); 
    // Return NO if you do not want the specified item to be editable. 
    if([[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"status"] isEqualToString:@"directory"]) 
     return YES; 
    else 
     return NO; 
} 

Code of Zeile löschen:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    if (editingStyle == UITableViewCellEditingStyleDelete) 
    { 
     [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB 
     [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array 
     [self updateListofSoundsFile]; /// Custom method 
    } 
} 

- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return NO; // i also tried to return YES; 
} 

Hier updateListofSoundsFile meine ist benutzerdefinierter Methodencode ist:

-(void)updateListofSoundsFile 
{ 
    if(self.listOfSounds.count > 0) 
     [self.listOfSounds removeAllObjects]; 

    self.listOfSounds = [self.sql_ getAllDataFromAudioTable]; // get all record from DB 
    NSLog(@"%d",self.listOfSounds.count); 

    [self.tblView reloadData]; 
} 

Bitte geben Sie einen Vorschlag, Wie kann ich dieses Problem lösen?
Thanks :)

+0

Veröffentlichen Sie Ihre Methode 'numberOfRowsInSection'. Frage - Warum rufen Sie in Ihrer 'commitEditingStyle'-Methode' updateListOfSoundsFile' auf? Sie aktualisieren bereits 'listOfSounds', indem Sie ein Objekt entfernen. Nachdem Sie das Objekt aus dem Array entfernt haben, rufen Sie einfach 'deleteRowsAtIndexPaths' auf, um eine Zeile aus der Tabelle zu entfernen.Stellen Sie außerdem sicher, dass Ihr Aufruf von "deleteSoundFileAudioTableWhereMainID" tatsächlich eine Zeile aus der Datenbank entfernt. – rmaddy

Antwort

5

müssen Sie aus dem Array von Tableview auch vor dem Löschen von Elementen roh entfernen und Daten nachladen diese Zeile mit von Array becouse entfernen Artikel aber nicht Tableview.

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    if (editingStyle == UITableViewCellEditingStyleDelete) 
    { 
     [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB 

     [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array 

     [self updateListofSoundsFile]; /// Custom method 
    } 
} 
+4

Dies sollte nicht die Lösung sein. 1 - Sie sollten die Daten immer aus der Datenquelle entfernen, bevor Sie die Tabelle aktualisieren. 2 - Wenn Sie 'reloadData' aufrufen, gibt es keinen Grund,' deleteRowsAtIndexPath: 'zuerst aufzurufen. Diese Lösung funktioniert möglicherweise, aber es versteckt ein anderes Problem. – rmaddy

+2

dann bitte führen Sie uns, was die richtige Lösung ist Sir bitte setzen Sie die Antwort mit der richtigen Lösung. danke –

+2

@ rmaddy-sir, wenn Sie andere beste Lösung dann bitte führen Sie uns, um das Wissen zu verbessern. Vielen Dank –

0
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    if (editingStyle == UITableViewCellEditingStyleDelete) 
    { 
     [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB 
     [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array 
     [self updateListofSoundsFile]; /// Custom method 
    } 
    [self.tblView reloadData]; 
} 
+0

Bitte erläutern Sie, wie dies das Problem löst? Die Methode 'updateListofSoundsFile' ruft bereits' reloadData' auf. – rmaddy

+0

Sie setzen UpdateListofSoundsFile außerhalb, wenn Bedingung ... – hitesh

2

Ich lief in das gleiche Problem. Das Problem war, dass ich das Objekt der Zelle löschte, aber als ich die reloadData Methode von tableView verwendete, wurde meine canEditRowAtIndexPath Methode nicht aufgerufen, was in der Lage ist, Zellen zu bearbeiten, die ich nicht bearbeiten möchte. Der wahre Fix war nicht die deleteRowsAtIndexPaths Methode, sondern die [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; Methode.

Grundsätzlich ist hier, was geschah:

Als ich reloadData genannt: Die Rohdaten wurden nicht von der tableView entfernt wird als die Nitin. Daher ist dies nicht die Lösung.

Wenn I genannt deleteRowsAtIndexPaths: IOS eine Diskrepanz zwischen den zugrunde liegenden Daten und der Anzahl der Zellen nachgewiesen (weil ich bereits die Aufgabe zugrunde, entfernt worden). Das Ergebnis war ein Absturz, der (offensichtlich) auch nicht die Lösung ist.

Jetzt für den Fix!

Als ich angerufen reloadRowsAtIndexPaths: Dies verursacht, dass die TabelleView einfach diese einzelne Zelle neu laden und es wurde los von den Rohdaten. Dies ist die Lösung.

Anstatt Entfernen des dataSource Objekt, dann versuchen, die Zelle zu entfernen, die im Wesentlichen durch nichts an dieser Stelle gesichert ist (die einen Absturz verursacht), entfernen Sie einfach das dataSource Objekt, dann nachladen, dass indexPath der tableView

hier ist das allgemeine Format der Methode:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (editingStyle == UITableViewCellEditingStyleDelete) 
    { 
     [myDataSourceArray removeObjectAtIndex:indexPath.row]; 
     [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
    } 
} 

Dies ist das erste Mal, dass ich mit dem Rest Rohdaten in der Ausgabe lief, die nicht einfach durch den Aufruf der Methode reloadData entfernt wird. Dies ist sicherlich die eleganteste Lösung, die ich bisher gesehen habe.

Happy Coding! Ich hoffe das hilft.

0

Wenn es mir kommt, analysiert ich wie folgt:

Wie rmaddy auf Nitin Gohel's Antwort kommentiert:

  1. Sie immer die Daten aus der Datenquelle, bevor die Aktualisierung der Tabelle entfernen sollte.

    Ich denke, das ist der ideale Weg.

  2. Wenn Sie reloadData anrufen, gibt es keinen Grund zum ersten Anruf deleteRowsAtIndexPath.

    Das sieht auch richtig aus.

Ich analysierte Mehrdeutigkeit, wenn ich reloadData sein crashishing schreiben, aber sobald ich deleteRowsAtIndexPath schreiben gut es funktioniert.

Hoffnung jemand zu diesem Thema für ihre Ursachen betonen wird usw.

0

die ‚removeObjectAtIndex: indexPath‘ dauert einige Zeit, und ich vermute, Ihr [self.tblView reload] früh genannt wird. Ich habe versucht, einen Beispielcode und gefunden Erfolg mit [UITableView beginUpdates] und [UITableView EndUpdates] Sie können auch Absturz vermeiden, wenn Sie vor dem Nachladen ein wenig Verzögerung setzen oder Löschen von Zeilen haben nicht versucht, es aber

[tableTable beginUpdates]; 
[tableArray removeObjectAtIndex:indexPath.row]; 
[tableTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
[tableTable endUpdates]; 
Verwandte Themen