Ответы:
По вашему didSelectRowAtIndexPath
необходимо позвонить, deselectRowAtIndexPath
чтобы отменить выбор ячейки.
Так что, что бы вы ни делали в didSelectRowAtIndexPath
себе, просто вызовите deselectRowAtIndexPath
это.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Do some stuff when the row is selected
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-deselectRowAtIndexPath:animated:
метод для своего свойства tableView из -viewDidAppear
. Однако, если у вас есть табличное представление в подклассе UIViewController, вам следует позвонить -deselectRowAtIndexPath:animated:
от -viewDidAppear
себя. :)
-viewWillAppear:
которое сломало его. Добавление звонка, чтобы [super viewWillAppear:animated]
он снова заработал.
UITableViewController
«S clearsSelectionOnViewWillAppear
свойство имеет значение YES
(значение по умолчанию), и вы не предотвратили [super viewWillAppear]
от призыва.
Самый чистый способ сделать это на 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];
}
}
Таким образом, у вас есть анимация затухания выделения при возвращении в контроллер, как и должно быть.
Взято с http://forums.macrumors.com/showthread.php?t=577677
Swift версия
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
Вызов может вернуть ноль, поэтому его следует проверить. В документации говорится : Путь индекса, идентифицирующий индексы строки и раздела выбранной строки, или nil, если путь индекса недопустим.
Вы подкласс -(void)viewWillAppear:(BOOL)animated
? Выбранный UITableViewCell не будет отменен, если вы не вызываете [super viewWillAppear:animated];
свой пользовательский метод.
Для пользователей Swift добавьте это в свой код:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
Это ответ Paulthenerd, за исключением Swift вместо Obj-C.
Обновлено с Swift 4
После нескольких экспериментов, также основанных на предыдущих ответах, я пришел к выводу, что наилучшего поведения можно достичь двумя способами: (практически идентично на практике)
// 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)
}
}
Я лично принимаю первое решение, потому что оно просто более лаконично. Другая возможность, если вам нужно немного анимации, когда вы вернетесь к своему tableView, это использовать 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)
}
}
И последнее, но не менее важное: если вы используете UITableViewController, вы также можете воспользоваться свойством clearsSelectionOnViewWillAppear .
Чтобы получить поведение, которое Кендалл Хелмстеттер Гелнер описывает в своем комментарии, вам, скорее всего, не нужен deselectRowAtIndexPath, а скорее свойство clearsSelectionOnViewWillAppear на вашем контроллере. Возможно, это было установлено в ДА случайно?
См. Комментарий в шаблоне Apple по умолчанию для новых подклассов UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
Я получал эту проблему также для моего приложения детализации. После того, как viewcontroller, который я назову VC, возвращается после нажатия другого ViewController, выбранная ячейка в VC остается выделенной. В моем приложении я создал VC для обработки второго уровня (из трех уровней) моего анализа.
Проблема в моем случае состоит в том, что VC был UIViewController (который содержал View, который содержал TableView). Вместо этого я сделал VC UITableViewController (который содержал TableView). Класс UITableViewController автоматически обрабатывает отмену выделения ячейки таблицы после возврата из толчка. Второй ответ на пост « Проблема с deselectRowAtIndexPath в tableView » дает более полный ответ на эту проблему.
Проблема не возникла для корневого viewcontroller, потому что, когда я создал приложение как «Приложение на основе навигации» в XCode, полученный корневой viewcontroller уже был создан для подкласса UITableViewController.
Если ни один из них не работает для вас, рассмотрите этот обходной путь:
Используйте раскрутить Segue, чтобы позвонить:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
Зачем это делать? Прежде всего, если у вас возникли проблемы с запуском кода отмены выбора в нужное время. У меня были проблемы с тем, что он не работал с viewWillAppear, поэтому раскрутка работала намного лучше.
шаги:
Запишите результаты раскрутки (или вставьте сверху) в свой первый ВК (тот, что со столом)
Перейти на 2-й ВК. Удерживая нажатой клавишу «Control», нажмите кнопку «Отмена» / «Готово» и т. Д., Которую вы используете, чтобы закрыть VC, и перетащите на значок «Выход» вверху.
Выберите секцию раскрутки, созданную на шаге 1
Удачи.
Я использую CoreData, поэтому код, который работал для меня, представлял собой комбинацию идей из различных ответов в Swift:
override func viewDidAppear(_ animated: Bool) {
if let testSelected = yourTable.indexPathForSelectedRow {
yourTable.deselectRow(at: testSelected, animated: true)
}
super.viewDidAppear(true)
}
У меня была такая же проблема в течение долгого времени, поэтому на случай, если кто-то еще борется:
Посмотрите на свой -tableView: cellForRowAtIndexPath:
и посмотрите, создаете ли вы ячейки или используете «идентификатор повторного использования». Если последнее, убедитесь, что в вашей таблице в IB есть ячейка с этим идентификатором. Если вы не используете идентификатор повторного использования, просто создайте новую ячейку для каждой строки.
Это должно дать вашей таблице ожидаемое «исчезновение выбранной строки» при появлении.
Для Swift 3: я бы предпочел использовать его в viewDidDisappear
Определить: -
var selectedIndexPath = IndexPath()
По мнениюDidDisappear: -
override func viewDidDisappear(_ animated: Bool) {
yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}
В didSelectRowAtIndexPath: -
func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
selectedIndexPath = indexPath
}
если ячейка остается выделенной после прикосновения к ней, вы можете вызвать метод UITabelView,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
`[tableView deselectRowAtIndexPath:indexPath animated:YES];`
}
Или вы можете использовать следующий метод и изменить его в соответствии с вашими требованиями,
// MARK: 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
У меня была такая же проблема, и я обнаружил, что оставил пустой вызов viewWillAppear в нижней части моего tableViewController. После того, как я удалил пустую функцию переопределения, строка больше не оставалась подсвеченной после возврата к представлению tableView.
проблемный функционал
override func viewWillAppear(_ animated: Bool) {
// need to remove this function if not being used.
}
удаление пустой функции решило мою проблему.
deselectRowAtIndexPath
в моем viewDidAppear, если при выборе строки открывается новое представление.