Відповіді:
У своєму 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
Швидка версія
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
Виклик може повернути нуль, тому його слід перевірити. У документації зазначено : шлях до індексу, що ідентифікує індекси рядків та розділів вибраного рядка, або нульовий, якщо шлях до індексу недійсний.
Ви підклас -(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 .
Щоб отримати поведінку, яку описує у своєму коментарі Кендалл Хелмстеттер Гельнер, ви, ймовірно, не хочете, щоб ви вибрали деселектРоуAtIndexPath, а, скоріше, властивість clersSelectionOnViewWillAppear на контролері. Можливо, це було задано ТАК випадково?
Дивіться коментар у стандартному шаблоні Apple для нових підкласів UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
Цю проблему я отримував і для свого додаткового додатку. Після того, як контролер перегляду, який я називаю VC, повертається після натискання іншого ViewController, вибрана комірка в VC залишається виділеною. У своєму додатку я створив VC для обробки другого рівня (з трьох рівнів) моєї деталізованої роботи.
Проблема в моєму випадку полягає в тому, що VC був UIViewController (який містив представлення, що містило TableView). Я замість цього зробив VC UITableViewController (який містив TableView). Клас UITableViewController автоматично обробляє розмежування комірки таблиці після повернення з натискання. Друга відповідь на пост " Проблема з deselectRowAtIndexPath у tableView " дає більш повну відповідь на цю проблему.
Проблема не виникала для кореневого контролера перегляду, тому що коли я створив додаток як "додаток для навігації" в XCode, отриманий кореневий вигляд-контролер вже був зроблений для підкласу UITableViewController.
Якщо жодне з цих питань не працює для вас, врахуйте це:
Використовуйте розмотаний мозок, щоб зателефонувати:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
Навіщо це робити? Перш за все, якщо у вас виникають проблеми з тим, щоб скинути код відбору в потрібний час. У мене були проблеми з тим, що я не працював на viewWillAppear, тому розмотка працювала набагато краще.
Кроки:
Запишіть розмотаний мозок (або вставте зверху) у свій 1-й ВК (той із таблицею)
Перейти до 2-го ВК. Перетягніть клавішу "Control" / "Скасувати" / "Готово" та "Etc", яку ви використовуєте, щоб відхилити цей 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 внизу моєї таблиціViewController. Після того, як я видалив порожню функцію заміщення, після повернення до подання tableView рядок більше не виділявся.
проблемний функц
override func viewWillAppear(_ animated: Bool) {
// need to remove this function if not being used.
}
видалення порожньої функції вирішило мою проблему.
deselectRowAtIndexPath
в моєму оглядіDidAppear, якщо виберіть рядок відкриває новий вид.