2013-08-23 11 views
5

W mojej aplikacji przeładować mój Tableview ([tablView reloadData];) po Usuń wiersz z Tableview następnie canEditRowAtIndexPath Metoda sprecyzowane wezwanie do (przepuszczalnego) całkowita liczba wierszy.W metodzie canEditRowAtIndexPath, reloadData z UITableView nie działa poprawnie?

Na przykład:

Jeżeli muszę rzędach na mego Tableview, a następnie usunąć wiersz z Tableview. Po usunięciu I przeładować mój Tableview ([tablView reloadData]) ale canEditRowAtIndexPath Metoda nazywa 5 czasu zamiast 4 razy ??

więc zawsze dostaje Po błąd:

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

Próbowałem też przeładować tabeli po pewnym opóźnieniem (używając NSTimer), ale to też nie pracował dla mnie.

umieścić jakiś kod tutaj:

ubiegać canEditRowAtIndexPath na określonego wiersza który @"status" isEqualToString:@"directory" takie jak,

- (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; 
} 

Kodeks Usuń wiersz:

- (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; 
} 

Tutaj updateListofSoundsFile jest mój Kod metody niestandardowej to:

-(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]; 
} 

Podaj wszelkie sugestie, Jak mogę rozwiązać ten problem?
Dzięki :)

+0

Opublikuj swoją metodę 'numberOfRowsInSection'. Pytanie: Dlaczego w metodzie 'commitEditingStyle' wywołujesz' updateListOfSoundsFile'? Już aktualizujesz 'listOfSounds', usuwając jeden obiekt. Po usunięciu obiektu z tablicy, po prostu wywołaj 'deleteRowsAtIndexPaths', aby usunąć jeden wiersz z tabeli.Sprawdź także, czy twoje wywołanie 'deleteSoundFileAudioTableWhereMainID' faktycznie usuwa jeden wiersz z bazy danych. – rmaddy

Odpowiedz

5

trzeba usunąć surowy z tableview również befor pozycji Usuń z tablicy i przeładować dane przy użyciu tej linii poniewaz usunąć element z tablicy, ale nie 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

To nie powinno być rozwiązaniem. 1 - zawsze powinieneś usunąć dane ze źródła danych przed aktualizacją tabeli. 2 - Jeśli zamierzasz wywołać 'reloadData', nie ma żadnego powodu, aby najpierw wywołać' deleteRowsAtIndexPath: '. To rozwiązanie może działać, ale ukrywa inne problemy. – rmaddy

+2

następnie proszę, poprowadź nas, co jest właściwym rozwiązaniem, proszę podaj odpowiedź odpowiednim rozwiązaniem. dziękuję za –

+2

@ rmaddy- sir, jeśli masz inne najlepsze rozwiązanie, proszę, poprowadź nas, aby poprawić wiedzę. dzięki –

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

Proszę wyjaśnić, jak to rozwiązuje problem? Metoda "updateListofSoundsFile" już wywołuje 'reloadData'. – rmaddy

+0

umieszczasz updateListofSoundsFile na zewnątrz, jeśli warunek ... – hitesh

2

wpadłem na ten sam problem. Problem polegał na tym, że usunąłem obiekt z komórki, ale gdy użyłem metody reloadData w metodzie , moja metoda canEditRowAtIndexPath nie została wywołana, co skutkowało możliwością edycji komórek, których nie chcę edytować. Prawdziwa poprawka nie wywoływała metody deleteRowsAtIndexPaths, ale metody [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];.

Zasadniczo oto co się dzieje:

Gdy zadzwoniłem reloadData: Surowe dane nie są usuwane z tableView jak Nitin powiedział. Dlatego nie jest to rozwiązanie.

Gdy zadzwoniłem pod numer deleteRowsAtIndexPaths: iOS wykrył rozbieżność między danymi bazowymi a liczbą komórek (ponieważ usunąłem już obiekt leżący u podstaw). Rezultatem była awaria, która również nie jest rozwiązaniem (oczywiście).

Teraz za poprawkę!

Kiedy zadzwoniłem pod numer reloadRowsAtIndexPaths: To spowodowało, że tableView po prostu przeładował tę pojedynczą komórkę I pozbył się nieprzetworzonych danych. To jest rozwiązanie.

Zamiast usuwania obiektu dataSource, a następnie próbuje usunąć komórki, która jest zasadniczo poparte nic w tym punkcie (który powoduje awarię), po prostu usunąć obiekt dataSource, a następnie załaduj że indexPath z tableView

Oto ogólny format metody:

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

jest to pierwszy raz, kiedy wpadł do emisji z pozostałego surowca danych, która nie jest usuwana po prostu przez wywołanie metody reloadData. Jest to z pewnością najbardziej eleganckie rozwiązanie, jakie dotychczas widziałem.

Happy Coding! Mam nadzieję, że to pomoże.

0

Jeśli chodzi o mnie, analizowano jak poniżej:

Jak komentował rmaddy na Nitin Gohel's odpowiedź:

  1. Należy przed aktualizacją tabeli zawsze usunąć dane ze źródła danych.

    Czuję, że to idealny sposób.

  2. Jeśli zamierzasz zadzwonić pod numer reloadData, nie ma żadnego powodu, aby najpierw zadzwonić pod numer deleteRowsAtIndexPath.

    To również wygląda poprawnie.

analizowałem niejasności, jeśli piszę reloadData jego crashishing ale gdy piszę deleteRowsAtIndexPath to działało dobrze.

nadzieję, że ktoś będzie podkreślać w tej sprawie do jego przyczyn itp

0

do „removeObjectAtIndex: indexPath” zajmuje trochę czasu i podejrzewam Twój [self.tblView reloadData] jest nazywany wcześnie. Próbowałem przykładowy kod i odniósł sukces z [UITableView beginUpdates] i [UITableView endUpdates] można również uniknąć katastrofy, jeśli umieścić trochę opóźnienia przed przeładunkiem lub usuwanie wierszy nie próbowałem to chociaż

[tableTable beginUpdates]; 
[tableArray removeObjectAtIndex:indexPath.row]; 
[tableTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
[tableTable endUpdates]; 
Powiązane problemy