2010-08-12 13 views
7

Mam splitViewController, który ma jako MasterViewController niektóre viewController i jako DetailViewController niektóre tableViewController. Po naciśnięciu przycisku na masterViewController chcę wyświetlić nowy tableViewController w detailViewController zamiast istniejącego.UITableView reloadData - cellForRowAtIndexPath nie został uruchomiony

Więc zrobiłem tak:

SearchDetailViewController *searchDetailViewController = [[SearchDetailViewController alloc] initWithStyle:UITableViewStylePlain]; 
UINavigationController *searchDetailNavigationController = [[UINavigationController alloc] initWithRootViewController:searchDetailViewController]; 

Po tym ja przekazywania danych, aby pokazać się w nowym tableController:

[searchDetailViewController passInSearchResults:listOfItems]; 

Potem "push" Nowe sterowniki do splitViewController:

[searchSplitViewController setViewControllers:[NSArray arrayWithObjects:self.navigationController, searchDetailNavigationController, nil]]; 

W tabeli docelowej metodaViewController przekazuje dane "passInSearchResults", a także wywołuje funkcję reloadDa ta. Metoda wygląda tak:

- (void)passInSearchResults:(NSMutableDictionary *)searchResults { 
    self.searchResultList = searchResults; 
    NSLog(@"Data is passed in: %@",self.searchResultList); 
    [self.tableView reloadData]; 
    //[self.tableView setNeedsDisplay]; 
} 

konsoli: Dane są przekazywane w: [tu uzyskać dokładne dane chcę i wydaje się tylko w prawo].

After this I see that method "numberOfRowsInSection" is fired: 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    NSLog(@"Setting table length: %i",[self.searchResultList count]); 
    return [self.searchResultList count]; 
} 

konsoli: Ustawianie długość stołu: [tu mam odpowiedniej długości]

Problem polega na tym, że tabela nie jest wypełniona przekazywanych danych i metoda „cellForRowAtIndexPath” nie nazywa.

Jak to możliwe, że na reloadData metoda "numberOfRowsInSection" jest uruchamiana, ale nie metoda "cellForRowAtIndexPath" ... ???

Dzięki

Odpowiedz

4

Jak to możliwe, że od sposobu reloadData "numberOfRowsInSection" jest zwolniony, ale nie metoda "cellForRowAtIndexPath" ... ???

Po spędzeniu jednego dnia z tym samym (ish) problemem, myślę, że znaleźliśmy tutaj błąd. Znalazłem jednak hack/obejść.

Jeśli zmienię tablicę (dodając/usuwając wartości lub całkowicie ją ponownie budując), która jest używana w mojej metodzie cellForRowAtIndexPath, wydaje się poprawnie wywoływać ponownie cellForRowAtIndexPath po ponownym załadowaniu danych.

Na przykład w moim cellForRowAtIndexPath mam coś takiego:

cell.textLabel.text = [[[self.searchResultsArrayWithSections objectAtIndex:indexPath.section] objectForKey:@"rowValues"] objectAtIndex:indexPath.row]; 

    return cell; 

Mam też sposób na zbudowanie tej tablicy, która jest wywoływana na viewDidLoad:

- (NSMutableArray *)splitIntoSectionsWithAlphabet:(NSMutableArray *)myArray 
{  
NSString *letters = @"abcdefghijklmnopqrstuvwxyz"; 
NSMutableArray *content = [NSMutableArray new]; 

//code to build array here, nothing special really 

return content; 
} 

Tak zauważyłem, że jeśli w szczególności wywołaj tę metodę ponownie w mojej tablicy searchResultsArrayWithSections przed wywołaniem reloadData, to faktycznie wywołuje poprawnie wszystkie metody UITableViewDelegate! (jak powiedziałem, hack, ale działa!)

//dirty hack, bug with cancel button and not realoding data, seems we have to modify this array before it will work correctly 
self.customerListArrayWithSections = [self splitIntoSectionsWithAlphabet:self.customerListArray]; 
[self.customerListTv reloadData]; 
1

Miałem ten sam problem, ale decyzja była bardzo prosta. Po pierwsze, czy możesz spróbować przewinąć stół w dół? tableView: cellForRow ... powinien zostać wywołany. Sprawdź wysokości nagłówków i zawartośćOffset dla tableView.

10

Sprawdź, czy jesteś w głównym wątku Dzwoniąc [self.tableView reloadData];

- (void)passInSearchResults:(NSMutableDictionary *)searchResults { 
if ([NSThread isMainThread]) { 
    self.searchResultList = searchResults; 
    NSLog(@"Data is passed in: %@",self.searchResultList); 
    [self.tableView reloadData]; 
} 
else { 
    [self performSelectorOnMainThread:@selector(passInSearchResults:) searchResults waitUntilDone:NO]; 
} 

}

+1

Nie jest konieczne sprawdzenie, czy najpierw uruchomiony jest główny wątek. Funkcja 'performSelectorOnMainThread' działa, nawet gdy już znajdujesz się w głównym wątku, podobnie jak' dispatch_async (dispatch_get_main_queue() '(prawdopodobnie to właśnie tutaj chcesz). Dodanie' if' tutaj po prostu zużywa niepotrzebne cykle procesora. –

4

Sprawdź numberOfRows, jeśli jest 0, nie ma komórki do wyświetlenia.

0

Możesz również przydzielać tabelę w init [z ...] metodą viewController, a także podłączyć tę samą właściwość do IB. W ten sposób jest możliwe, że numberOf ... delegate metody są wywoływane, a cellForRow ... nie.

0

"UITableView nie wywołał cellForRowAtIndexPath na reloadData, ponieważ ustawiłem ramkę przez pomyłkę.

_tableView = [[UITableView alloc] initWithFrame:self.view.frame]; 
_tableView.translatesAutoresizingMaskIntoConstraints = NO; 

Zmieniając go CGRectZero, działało ..

_tableView = [[UITableView alloc] initWithFrame:CGRectZero]; 
_tableView.translatesAutoresizingMaskIntoConstraints = NO; 
2

W moim przypadku problemem było to, że funkcja reloadData() nie został wywołany z głównym wątku.

Zmieniłem to poprzez umieszczenie go w dispatch_async() funkcji, która rozwiązała problem:

dispatch_async(dispatch_get_main_queue(), { 
    self.tableView.reloadData() 
}) 

Nadzieja to pomaga innym.

Powiązane problemy