2013-04-09 12 views
6

w mojej aplikacji Mam UITabeView z UITextField s wewnątrz każdej komórki. Mam jednak problemy z zaimplementowaniem przycisków previous/next, aby pole tekstowe wewnątrz poprzedniego/następnego UITableViewCell było pierwszym obiektem odpowiadającym.Implementacja przycisków Poprzedni/Następny tekst w widoku UITableView w celu uczynienia pierwszego respondenta UITextField w niewidocznej komórce

Podklasowałem klasę UITableViewCell, aby wywołać określoną metodę jej delegate po naciśnięciu przycisków prev./next i przekazaniu samej komórki jako parametru tej metody (dzięki czemu mogę uzyskać jej ścieżkę indeksu obliczyć, który jest ścieżką indeks komórce, którego pole tekstowe musi być wykonany pierwszy responder)

W realizacji metody delegata I:

  • uzyskać ścieżkę indeksu komórki, której przycisk został naciśnięty
  • dodać lub odjąć 1 od indeksu pa th z tej komórki (w zależności, na którym został naciśnięty przycisk)
  • dostać komórkę którego textfield musi być wykonany pierwszy responder używając metody -cellForRowAtIndexPath: na widoku tabeli
  • uczynić pole tekstowe first responder

problemu jest to, że metoda -cellForRowAtIndexPath: zwraca komórkę tylko wtedy, gdy jest widoczna. Więc gdy komórka nie jest widoczna, zwróci ona nil, a powyższy algorytm nie zadziała, a gdy komórka jest na ekranie, będzie działać poprawnie.

Oto mój kod dla prev. przycisk, pod warunkiem, że MUInfoMateriaTableViewCell jest mój podklasa UITableViewCell i że ma właściwość textField zwracającą jego pola tekstowego:

- (void)prevButtonPressedInCell:(MUInfoMateriaTableViewCell *)cell 
{ 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 
    NSIndexPath *previousIndexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:indexPath.section]; 

    MUInfoMateriaTableViewCell *newCell = (MUInfoMateriaTableViewCell *)[self.tableView cellForRowAtIndexPath:previousIndexPath]; 
    [newCell.textField becomeFirstResponder]; 
} 

Czy istnieje jakiś sposób, aby „dostać” do komórki, która nie jest widoczna, więc mogę zrobić jego tekst pole pierwszy odpowiadający? Czy możesz zaproponować mi inny algorytm do obejścia tego problemu?

Odpowiedz

7

Można rozwiązać ten problem z procesem wieloetapowym:

  • śledzić komórki, która zawiera pole tekstowe pożądaną, aby first responder
  • obliczyć NSIndexPath komórki, która ma zostać wyświetlona i zadzwoń pod numer , aby wyświetlić ją pod numerem
  • implementuj tableView:willDisplayCell:forRowAtIndexPath:, aby zadzwonić pod numer becomeFirstResponder od pożądanej komórki, gdy staje się widoczne i pasuje żądaną komórkę lub indeksu ścieżkę

Ostatnim krokiem jest ważne, ponieważ wywołanie becomeFirstResponder nie robi nic, jeśli odbiornik nie jest podrzędny z każdego okna.

+0

Jak zasugerować śledzenie komórki, której pole tekstowe powinno być pierwszym reagowaniem? Czy powinienem mieć coś takiego jak 'activeCellIndexPath' i sprawdzić, czy ścieżka indeksu aktywnej komórki pasuje do ścieżki indeksu komórki przekazanej jako parametr w' tableView: willDisplayCell: forRowAtIndexPath: 'czy jest tam lepszy/bardziej wydajny? podejście? – BigLex

+0

Wdrażałbym dokładnie to, co właśnie opisałeś. Pamiętaj, aby obsłużyć przypadek, w którym nie chcesz, aby jakaś komórka odpowiadała i 'nil' out 'activeCellIndexPath'. – jszumski

+0

OK! Dziękuję Panu! – BigLex

3

Włącz widoczność komórki, przewijając widok tabeli, używając scrollToRowAtIndexPath:atScrollPosition:animated:.

Na przykład

- (void)prevButtonPressedInCell:(MUInfoMateriaTableViewCell *)cell 
{ 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 
    NSIndexPath *previousIndexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:indexPath.section]; 

    [self.tableView scrollToRowAtIndexPath:previousIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

    MUInfoMateriaTableViewCell *newCell = (MUInfoMateriaTableViewCell *)[self.tableView cellForRowAtIndexPath:previousIndexPath]; 
    [newCell.textField becomeFirstResponder]; 
} 
-1

problem jest taki, że -cellForRowAtIndexPath: sposób powraca komórki tylko wtedy, gdy jest widoczna.

Dzieje się tak dlatego, że komórka nie istnieje, gdy jej rząd nie jest widoczny. UITableView przechowuje tylko te komórki, których potrzebuje do narysowania tabeli. Dlatego podczas przewijania tabeli otrzymujesz wiele wiadomości -tableView:cellForRowAtIndexPath: - tabela prosi o źródło danych, aby dostarczyć komórki, których nie ma.

Jeśli chcesz użyć obecnego podejścia, musisz przewinąć tabelę tak, aby wiersz, który ma być edytowany, był widoczny, co wykazano w odpowiedzi Gabriele Petronelli.

+0

To jest po prostu złe. Spójrz na typową implementację 'tableView: cellForRowAtIndexPath:', a zobaczysz, co się stanie. Zawsze zwraca komórkę, ale może być konieczne utworzenie nowej komórki dla tej ścieżki indeksu, jeśli nie jest ona obecnie widoczna. Lub może nadal mieć to w pamięci podręcznej komórki, w którym to przypadku usunie i zwróci już istniejącą komórkę. – Logachu

+0

@Logachu Moja odpowiedź jest poprawna w kontekście pierwotnego pytania, ale niepoprawna edycja zmieniła '-cellForRowAtIndexPath:' (metodę UITableView) na '-tableView: cellForRowAtIndexPath:' (metoda UITableViewDataSource), która zmienia pytanie. Musiało to nastąpić mniej więcej w tym samym czasie, kiedy odpowiadałem, ponieważ skopiowałem niepoprawny tekst do cytatu w mojej odpowiedzi. Naprawiłem cytat i pytanie, i jeśli czytasz moją odpowiedź z myślą o UITableView (i może sprawdzam [dokumenty] (http://bit.ly/KF1He4)) Mam nadzieję, że zgodzisz się, że to jest poprawne. – Caleb

Powiązane problemy