Odpowiedzi:
W twoim didSelectRowAtIndexPath
musisz zadzwonić, deselectRowAtIndexPath
aby odznaczyć komórkę.
Więc cokolwiek jeszcze w niej robisz didSelectRowAtIndexPath
, po prostu każ deselectRowAtIndexPath
.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Do some stuff when the row is selected
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-deselectRowAtIndexPath:animated:
metodę w swojej właściwości tableView z -viewDidAppear
. Jeśli jednak masz widok tabeli w podklasie UIViewController, powinieneś wywołać -deselectRowAtIndexPath:animated:
od -viewDidAppear
siebie. :)
-viewWillAppear:
które go zepsuło. Dodanie połączenia, aby [super viewWillAppear:animated]
znów działało.
UITableViewController
„s clearsSelectionOnViewWillAppear
właściwość jest ustawiona na YES
(co jest domyślne), a ty nie zapobiegły [super viewWillAppear]
z której dzwonimy.
Najprostszym sposobem na to jest viewWillAppear:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Unselect the selected row if any
NSIndexPath* selection = [self.tableView indexPathForSelectedRow];
if (selection) {
[self.tableView deselectRowAtIndexPath:selection animated:YES];
}
}
W ten sposób masz animację wygaszania zaznaczenia po powrocie do kontrolera, tak jak powinno.
Zaczerpnięte z http://forums.macrumors.com/showthread.php?t=577677
Szybka wersja
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// deselect the selected row if any
let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
if let selectedRowNotNill = selectedRow {
tableView.deselectRow(at: selectedRowNotNill, animated: true)
}
}
viewDidAppear
.
indexPathForSelectedRow
Wywołanie może zwrócić nil, więc powinno być sprawdzone. Dokumentacja stwierdza : Ścieżka indeksu identyfikująca indeksy wierszy i sekcji wybranego wiersza lub zero, jeśli ścieżka indeksu jest nieprawidłowa.
Czy masz podklasę -(void)viewWillAppear:(BOOL)animated
? Wybrana UITableViewCell nie zostanie odznaczona, gdy nie wywołasz [super viewWillAppear:animated];
metody niestandardowej.
Dla użytkowników Swift dodaj to do swojego kodu:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
To odpowiedź Paulthenerda, z wyjątkiem Swift zamiast Obj-C.
Zaktualizowano za pomocą Swift 4
Po kilku eksperymentach, również opartych na wcześniejszych odpowiedziach, doszedłem do wniosku, że najlepsze zachowanie można osiągnąć na 2 sposoby: (w praktyce prawie identyczne)
// First Solution: delegate of the table View
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
}
// Second Solution: With the life cycle of the view.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
if let selectedRow = selectedRow {
tableView.deselectRow(at: selectedRow, animated: false)
}
}
Osobiście przyjmuję pierwsze rozwiązanie, ponieważ jest po prostu bardziej zwięzłe. Inną możliwością, jeśli potrzebujesz trochę animacji po powrocie do tableView, jest użycie viewWillAppear
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let selectedRow: IndexPath? = _view.tableView.indexPathForSelectedRow
if let selectedRow = selectedRow {
_view.tableView.deselectRow(at: selectedRow, animated: true)
}
}
Wreszcie, jeśli używasz UITableViewController, możesz również skorzystać z właściwości clearsSelectionOnViewWillAppear .
Aby uzyskać zachowanie, które Kendall Helmstetter Gelner opisuje w swoim komentarzu, prawdopodobnie nie chcesz deselectRowAtIndexPath, ale raczej właściwości clearsSelectionOnViewWillAppear na kontrolerze. Być może przez przypadek został ustawiony na TAK?
Zobacz komentarz w domyślnym szablonie Apple dla nowych podklas UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
Ten problem występował również w przypadku mojej aplikacji do przechodzenia do szczegółów. Po tym, jak kontroler widoku, który nazwiemy VC, powróci po wciśnięciu innego kontrolera ViewController, wybrana komórka w VC pozostała podświetlona. W mojej aplikacji utworzyłem VC, aby obsłużyć drugi poziom (z trzech poziomów) mojego drążenia.
Problem w moim przypadku polega na tym, że VC był UIViewController (który zawierał View, który zawierał TableView). Zamiast tego zrobiłem VC jako UITableViewController (który zawierał TableView). Klasa UITableViewController automatycznie obsługuje usuwanie podświetlenia komórki tabeli po powrocie z wypychania. Druga odpowiedź na post „ Problem z deselectRowAtIndexPath w tableView ” daje pełniejszą odpowiedź na ten problem.
Problem nie wystąpił w przypadku głównego kontrolera widoku, ponieważ kiedy utworzyłem aplikację jako „aplikację opartą na nawigacji” w XCode, wynikowy główny kontroler widoku został już utworzony w podklasie UITableViewController.
Jeśli żadne z tych rozwiązań nie działa, rozważ to obejście:
Użyj odprężającej kolejki, aby zadzwonić:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
Czemu to robić? Przede wszystkim, jeśli masz problemy z uruchomieniem kodu odznaczenia we właściwym czasie. Miałem problem z tym, że nie działał on na widoku WillAppear, więc odprężenie działało znacznie lepiej.
Kroki:
Napisz rozwijanie płynności (lub wklej od góry) do pierwszego VC (tego z tabelą)
Idź do drugiego VC. Przeciągnij z wciśniętym klawiszem Control z przycisku Anuluj / Gotowe / Etc, którego używasz, aby odrzucić ten WK i przeciągnij do ikony Zakończ u góry.
Wybierz rozwijanie płynnej ścieżki utworzonej w kroku 1
Powodzenia.
Używam CoreData, więc kod, który działał dla mnie, był połączeniem pomysłów z różnych odpowiedzi, w Swift:
override func viewDidAppear(_ animated: Bool) {
if let testSelected = yourTable.indexPathForSelectedRow {
yourTable.deselectRow(at: testSelected, animated: true)
}
super.viewDidAppear(true)
}
Od dłuższego czasu mam ten sam problem, więc na wypadek, gdyby ktoś inny miał problemy:
Przyjrzyj się swojemu -tableView: cellForRowAtIndexPath:
i zobacz, czy tworzysz komórki, czy używasz „identyfikatora ponownego wykorzystania”. Jeśli to drugie, upewnij się, że twoja tabela w IB ma komórkę z tym identyfikatorem. Jeśli nie używasz identyfikatora ponownego wykorzystania, po prostu utwórz nową komórkę dla każdego wiersza.
To powinno dać twojej tabeli oczekiwany efekt „zanikania wybranego wiersza” po pojawieniu się.
W przypadku Swift 3: wolałbym, aby był używany w widokuDidDisappear
Definiować:-
var selectedIndexPath = IndexPath()
W widoku Zniknął: -
override func viewDidDisappear(_ animated: Bool) {
yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}
W didSelectRowAtIndexPath: -
func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
selectedIndexPath = indexPath
}
jeśli komórka pozostaje podświetlona po dotknięciu, można wywołać metodę UITabelView,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
`[tableView deselectRowAtIndexPath:indexPath animated:YES];`
}
Możesz też skorzystać z poniższej metody i zmodyfikować ją zgodnie ze swoimi wymaganiami,
// ZNAK: UITableViewDelegate
func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = UIColor.greenColor()
}
}
func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = UIColor.blackColor()
}
}
Xcode 10, Swift 4
Miałem ten sam problem i odkryłem, że zostawiłem puste wywołanie viewWillAppear na dole mojego tableViewController. Po usunięciu pustej funkcji nadpisywania wiersz nie był już podświetlony po powrocie do widoku tableView.
problem func
override func viewWillAppear(_ animated: Bool) {
// need to remove this function if not being used.
}
usunięcie pustej funkcji rozwiązało mój problem.
deselectRowAtIndexPath
w moim viewDidAppear, jeśli zaznaczenie wiersza spowoduje wyświetlenie nowego widoku.