2010-05-10 12 views
54

Po naciśnięciu widoku po wybraniu przez użytkownika wiersza UITableView wiersz dostaje niebieskie podświetlenie, a następnie pojawia się nowy widok. W porządku. Ale kiedy wracam, wiersz jest nadal podświetlony na niebiesko. Oto mój kod didSelectRowAtIndexPath.Wybrana opcja UItableViewCell pozostaje niebieska po wybraniu

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:@"SettingsView" bundle:nil]; 
    [[self navigationController] pushViewController:controller animated:YES]; 
    [controller release], controller = nil; 
} 

Co robię źle?

Odpowiedz

170

Zgodnie z powyższymi odpowiedziami, należy jawnie odznaczyć wiersz. Masz dwie opcje, jak to zrobić. Pierwszy z nich, to natychmiast wyłącz wiersz po wybór:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    ... 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

To będzie działać dobrze, ale nie jest alternatywą, a jego podejście przyjęte przez UITableViewController który jest pozostawienie wybrany wiersz następnie odznaczyć go, gdy widok pojawia się ponownie (po tym, jak kontroler, który naciskasz, jest wyskakiwany ze stosu).

Ma to niewielką zaletę, że użytkownik widzi przebłysk poprzedniego wyboru po powrocie, aby zobaczyć, co wybrał wcześniej.

Aby to realizować, wystarczy zastąpić viewWillAppear:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; 
} 

Jak powiedziałem, to co domyślny realizacji UITableViewController „s viewWillAppear: robi więc jeśli używasz UITableViewController i nie obejrzeniu to zachowanie, powinieneś sprawdzić, czy wywołujesz implementację super w klasie 'własnej viewDidAppear:.

Aktualizacja (30 października 2013): Cóż, jest to popularna odpowiedź! Jak słusznie zauważa Ben w komentarzach, UITableViewController faktycznie robi to w viewWillAppear: nie viewDidAppear: - to jest właściwy czas. Ponadto włącza się i wyłącza to zachowanie za pomocą właściwości clearsSelectionOnViewWillAppear użytkownika UITableViewController. Poprawiłem powyższą odpowiedź, aby to odzwierciedlić.

+0

naprawdę ładne. Dzięki za to. – ToddB

+0

@Luke Redpath niesamowite ... Dzięki – death7eater

+1

Jest to świetna odpowiedź, ale proponuję, że powinno to być umieszczone w 'viewWillAppear', aby dokładnie naśladować czas odznaczenia UITableViewController. –

7

Trzeba go odznaczyć:

[tableView deselectRowAtIndexPath:indexPath animated:YES];

3

Wystarczy zadzwonić [Tableview deselectRowAtIndexPath: indexPath animowany: tak].

1

Domyślne zachowanie UITableViewController usuwa zaznaczenie wiersza, gdy użytkownik powraca z widoku szczegółowego. Odpowiedź udzielona przez Luke'a jest w porządku, ale chcę wskazać powód:

1- Jeśli masz swój UITableViewController, jak to było, gdy został utworzony od zera, będziesz miał wszystkie domyślne zachowania.

2- Jeśli w sytuacji 1 dodasz -viewWillAppear lub -viewDidAppear, to będziesz nadpisywać standardowe zachowanie. Jeśli chcesz, aby wiersz odznaczał się po powrocie, musisz jednoznacznie powiedzieć, że chcesz go odznaczyć, tak jak zawsze!Aby to osiągnąć, jak mówi Łukasz, należy zadzwonić [super viewWillAppear:animated] lub [super viewDidAppear:animated] takiego:

-(void)viewWillAppear:(BOOL)animated { 

    [super viewWillAppear:animated]; 

    // Here goes all of your stuff 
} 
0

Innym rozwiązaniem jest wywołanie UITableView za reloadData w viewWillAppear

+0

Tak, ale uważam, że uważane jest za dobrą formę nie posypania kodu za pomocą wywołań do ponownego załadowania. Często jest bardziej wydajne rozwiązanie. –

4

Jeśli kontroler oparty jest na UITableViewController, masz tę funkcję wolny. Ale często kończyłem używać UIViewController bez. innych elementów oprócz UITableView, w takim przypadku należy zastąpić swój viewWillAppear do

-(void) viewWillAppear:(BOOL)animated{ 
    // Unselect the selected row if any 
    NSIndexPath* selection = [devListTableview indexPathForSelectedRow]; 
    if (selection){ 
     [tableview deselectRowAtIndexPath:selection animated:YES]; 
    } 
} 
11

UITableViewController ma właściwość BOOL o nazwie clearsSelectionOnViewWillAppear który robi dokładnie to, co chcesz.

Domyślnie jest ustawiony na YES, ale zauważyłem, że można (czasami przypadkowo) wyłączyć tę właściwość, wprowadzając własną metodę viewWillAppear:. Myślę, że dzieje się tak dlatego, że cofnięcie wyboru następuje podczas [UITableViewController viewWillAppear:], które może nigdy nie zostać wywołane, jeśli je przesłonisz.

Rozwiązanie jest proste. Wystarczy zadzwonić wersję Super koszulka z viewWillAppear: gdzieś w swojej wersji tej metody:

- (void)viewWillAppear:(BOOL)animated { 
    // Your custom code. 
    [super viewWillAppear:animated]; 
} 

Apple zaleca zawsze dzwoni super wersję dowolnego widoku {Czy Will} {A, Disa} metody ppear jeśli je zastąpić.

Referencje

Powiązane problemy