Как я могу отключить выбор UITableView?

1194

Когда вы нажимаете на строку в UITableView, строка выделяется и выбирается. Можно ли это отключить, так что нажатие строки ничего не делает?

DavidM
источник
17
Оригинальный вопрос имеет плохое название. OP хочет в первую очередь отключить selection, и, конечно, highlightingотключается с этим. Многие ответы с высоким рейтингом объясняют, как disable selectionи не относится к отключению highlighting. Чтобы отключить только подсветку используйте cell.selectionStyle = .Noneили перейдите наstoryboard / cell / Selection = None
Andrej
Пожалуйста, обновите заголовок или пост. Я смущен. И исходя из этого вопроса, я понятия не имею, для чего предназначены ответы.
Даниэль Спрингер

Ответы:

605

Для меня следующее работало нормально:

tableView.allowsSelection = false

Это означает, что didSelectRowAt#просто не будет работать. То есть прикосновение к ряду стола как таковое абсолютно ничего не даст. (И, следовательно, очевидно, никогда не будет выбранной анимации.)

(Обратите внимание, что если в ячейках у вас есть UIButtonили какие-либо другие элементы управления, конечно, эти элементы управления будут по-прежнему работать. Любые элементы управления, которые у вас есть в ячейке таблицы, полностью не связаны со способностью UITableView разрешить вам «выбирать строку» используя didSelectRowAt#.)

Еще один момент, на который следует обратить внимание: это не работает, когда UITableViewнаходится в режиме редактирования. Чтобы ограничить выбор ячеек в режиме редактирования, используйте код как показано ниже:

tableView.allowsSelectionDuringEditing = false 
Let's_Create
источник
6
это, наконец, сработало для меня, я попытался использовать cell.selectionStyle = UITableViewCellSelectionStyleNone; но это не сработало. Стоит отметить: это должно быть: tableView.allowsSelection = NO; не ложь
tony.tc.leung
6
Я думаю, это лучший вариант. При этом кнопки на ячейках активны, но текст неактивен.
Фахим Паркар
513
Как это принятый ответ и имеет столько голосов? Это не отвечает на вопрос вообще! Вам необходимо установить selectionStyleсвойство для ячейки: cell.selectionStyle = UITableViewCellSelectionStyle.Noneв Swift или cell.selectionStyle = UITableViewCellSelectionStyleNoneв Objective-C.
база узлов
5
Это работает для меня в быстрой 2.tableView.allowSelection = false
Ханад
15
Есть несколько способов сделать это в зависимости от желаемого. Ни стиль выделения, ни выбор не могут работать или могут потерпеть неудачу. Вот пример. Если вы хотите выбрать ячейку и вызвать tableViewDidSelectRowAtIndexPathее, cell.selectionStyle = .Noneжелательно. Если вы не хотите, чтобы эта функция-делегат вызывалась (или имела текстовое поле в tableViewCell), или нет tableView.allowsSelection = false.
Made2k
1965

Все, что вам нужно сделать, это установить стиль выделения для UITableViewCellэкземпляра, используя либо:

Objective-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

или

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Свифт 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None

Свифт 3 и 4.х:

cell.selectionStyle = .none

Кроме того, убедитесь, что вы либо не внедрили -tableView:didSelectRowAtIndexPath:в свой делегат табличного представления, либо явно исключили ячейки, для которых вы не хотите выполнять никаких действий, если вы это реализуете.

Больше информации здесь и здесь

Мартин Гордон
источник
122
@ Тони Это плохая идея, если внутри ячейки есть UITextField.
Анируддх Джоши
73
@TonyMillion также плохая идея, если вы хотите использовать встроенные элементы управления для редактирования, такие как пролистывание для удаления. Если для userInteractionEnabled установлено значение NO, кнопка удаления не будет реагировать на события касания пользователя.
Карлос П
47
поздно в этот поток, но вместо userInteraction, используйте cell.allowsSelection. Это останавливает методы взаимодействия ячейки, но не блокирует обычные вещи респондента UIView.
Крис C
4
Установка cell.userInteractionEnable = No не остановит срабатывание didSelectRowAtIndexPath.
user4951 15.10.12
25
Я буду голосовать за ответ, но для ясности, ОП попросил только отключить «выделение», нет, чтобы отключить взаимодействие всей ячейки, поэтому все эти комментарии являются оффтопическими.
Фредерик Йесид Пенья Санчес
353

Поскольку я недавно прочитал этот пост, и он мне помог, я хотел опубликовать еще один ответ, чтобы объединить все ответы (для потомков).



Итак, на самом деле есть 5 разных ответов в зависимости от желаемой логики и / или результата:

1.Чтобы отключить синюю подсветку, не меняя других взаимодействий ячейки:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Я использую это, когда у меня есть UIButton - или некоторые другие элементы управления - размещенные в UITableViewCell, и я хочу, чтобы пользователь мог взаимодействовать с элементами управления, но не с самой ячейкой.

НОТА : как отметил Тони Миллион выше, это НЕ мешает tableView:didSelectRowAtIndexPath:. Я обхожу это с помощью простых «если» утверждений, чаще всего проверяя раздел и избегая действий для конкретного раздела.

Другой способ, которым я подумал проверить на постукивание по ячейке:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // A case was selected, so push into the CaseDetailViewController
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.selectionStyle != UITableViewCellSelectionStyleNone) {
        // Handle tap code here
    }
}



2. Чтобы сделать это для всей таблицы, вы можете применить вышеуказанное решение к каждой ячейке таблицы, но вы также можете сделать это:

[tableView setAllowsSelection:NO];

В моем тестировании это все еще позволяет элементам управления UITableViewCellбыть интерактивными.


3. Чтобы сделать ячейку доступной только для чтения, вы можете просто сделать это:

[cell setUserInteractionEnabled:NO];



4. Сделать всю таблицу «только для чтения»

[tableView setUserInteractionEnabled:NO];



5. Чтобы на лету определить, следует ли выделять ячейку (которая в соответствии с этим ответом подразумевает выбор), вы можете реализовать следующий UITableViewDelegateметод протокола:

- (BOOL)tableView:(UITableView *)tableView 
   shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
mbm29414
источник
3
Если вы загрузите дизайн ячейки из пера, флажок (в IB) будет отлично работать для # 3 (и для таблиц для # 4). Для № 4 против № 2, разница в том, будут ли элементы управления внутри ячейки интерактивными?
lilbyrdie
4
Да. Если вы хотите отключить выбор, но разрешить UIButtons и т. Д. Продолжать поддерживать взаимодействие с пользователем, используйте # 2. Если вам нужна ячейка только для чтения, используйте # 4. Конечно, почему вы не имеете ничего, кроме UIViews или UILabels в неинтерактивной ячейке, мне не понятно. Может быть, кто-то захочет отключить все взаимодействия, пока происходит что-то еще.
mbm29414
8
# 4 - ужасная идея, это также отключит прокрутку в табличном представлении
simon
4
@ Simon На самом деле, это не страшная идея; это один из вариантов, который может или не может быть хорошим вариантом в зависимости от ваших обстоятельств. Также # 4 отключает прокрутку ПОЛЬЗОВАТЕЛЕМ; Вы все еще можете реализовать свой собственный, если это необходимо. Я согласен, что № 4 не очень полезен, но это не ужасная идея.
mbm29414
3
Для полноты, пожалуйста, добавьте крик tableView:shouldHighlightRowAtIndexPath:, который, как правило (не всегда), является моим предпочтительным подходом.
Бенджон
82

Подводя итог, я считаю, правильные ответы, основанные на моем собственном опыте в реализации этого:

Если вы хотите отключить выбор только для некоторых ячеек, используйте:

cell.userInteractionEnabled = NO;

Помимо предотвращения выбора, это также останавливает tableView: didSelectRowAtIndexPath: вызывается для ячеек, для которых он установлен. (Благодарю Тони Миллиона за этот ответ, спасибо!)

Если в ваших ячейках есть кнопки, на которые нужно нажать, вместо этого вам нужно:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

и вам также нужно игнорировать любые щелчки по ячейке в - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath .

Если вы хотите отключить выбор для всей таблицы, используйте:

tableView.allowsSelection = NO;

(Благодарю Пауло Де Барроса, спасибо!)

JosephH
источник
Что делать, если у нас есть кнопка в нашей клетке?
Умайр Афзал
56

Начиная с iOS 6.0, UITableViewDelegateимеет tableView:shouldHighlightRowAtIndexPath:. (Читайте об этом в документации iOS .)

Этот метод позволяет пометить определенные строки как несущественные (и неявно, не выбираемые) без необходимости изменять стиль выбора ячейки, связываться с обработкой событий ячейки userInteractionEnabled = NOили любыми другими методами, описанными здесь.

cbowns
источник
2
Наткнулся на эту ветку, и я был шокирован, увидев так много других ответов до этого. Это, без сомнения, правильный путь.
beebcon
2
Это действительно правильный и единственный ответ, который следует учитывать. Все остальное, упоминающее userInteraction, совершенно неверно.
Mattyohe
50

Вы также можете отключить выбор строки в самом конструкторе интерфейса, выбрав один NoSelectionиз selectionпараметров (свойств UITableView) на панели инспектора, как показано на рисунке ниже.

Инспектор UITableView

виньеш кумар
источник
2
Лучшее решение ИМХО
Итай Спектор
Я часто использую это решение
Евсеньев
46

ФИКСИРОВАННОЕ РЕШЕНИЕ ДЛЯ SWIFT 3

cell.selectionStyle = .none
МАНИШ ПАТАК
источник
36

В вашем UITableViewCell«s XIB в Attribute Inspector установленное значение Selectionдля None.

введите описание изображения здесь

Зайд Патан
источник
Это именно то, что мне было нужно. Я все еще хотел уведомление didSelect ..., но без видимой индикации выбора. Спасибо!
Тимоти Трипп
Рад, что это помогло! :)
Заид Патан
35

Если вы хотите, чтобы выделение только мигало, а не оставалось в выбранном состоянии, вы можете позвонить, в

didSelectRowAtIndexPath

последующий

[tableView deselectRowAtIndexPath:indexPath animated:YES];

поэтому он будет мигать выбранное состояние и вернуться.

Крис Фокс
источник
3
При таком подходе строка мгновенно подсвечивается, а затем затухает в течение полсекунды. Так Apple разрабатывает свои меню настроек, так что мне это нравится.
VinceFior
34

В случае, если кому-то нужен ответ для Swift :

cell.selectionStyle = .None
Акс
источник
1
мы можем также использовать эту cell.selectionStyle = UITableViewCellSelectionStyle.None
bably
29

Это то, что я использую, при cellForRowAtIndexPathнаписании этого кода.

cell.selectionStyle = UITableViewCellSelectionStyleNone;
Ахсан Эбрахим
источник
28

Из UITableViewDelegateпротокола вы можете использовать метод, willSelectRowAtIndexPath и return nilесли вы не хотите, чтобы выбранная строка.

Таким же образом вы можете использовать willDeselectRowAtIndexPathметод, и return nilесли вы не хотите отменять выделение строки.

user41806
источник
5
Мне не нравится этот метод, потому что он все еще показывает ячейку в подсвеченном состоянии, пока не подправится.
kbanman
2
это именно то, почему мне это нравится :-)
Joris Weimar
24

1- Все, что вам нужно сделать, это установить стиль выделения дляUITableViewCell экземпляра, используя либо:


Objective-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

или

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];


Свифт 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None


Свифт 3:

cell.selectionStyle = .none


2 - Не реализовывать - tableView:didSelectRowAtIndexPath:в вашем табличном представленииdelegate или явно исключите ячейки, которые вы не хотите выполнять, если вы реализуете это.

3 - Далее, вы также можете сделать это из раскадровки. Щелкните ячейку табличного представления и в инспекторе атрибутов под ячейкой табличного представления измените раскрывающийся список рядом с «Выделением» на «Нет».


4 - Вы можете отключить подсветку ячейки таблицы, используя следующий код в (iOS) Xcode 9, Swift 4.0

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let cell = tableView.dequeueReusableCell(withIdentifier: "OpenTbCell") as! OpenTbCell
        cell.selectionStyle = .none
        return cell


}
parvind
источник
20

Objective-C:

  1. Ниже фрагмент отключает подсветку, но также отключает вызов didSelectRowAtIndexPath. Так что, если вы не реализуете, didSelectRowAtIndexPathиспользуйте метод ниже. Это должно быть добавлено при создании таблицы. Это будет работать на кнопках и UITextFieldвнутри ячейки.

    self.tableView.allowsSelection = NO;
  2. Ниже фрагмент отключает подсветку и не отключает вызов didSelectRowAtIndexPath. Установите стиль выделения ячейки на Нет вcellForRowAtIndexPath

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
  3. Ниже фрагмент отключить все в ячейке. Это отключит взаимодействие с buttons, textfields:

    self.tableView.userInteractionEnabled = false;

Swift:

Ниже приведены Swiftэквиваленты вышеуказанных Objective-Cрешений:

  1. Замена первого решения

    self.tableView.allowsSelection = false
  2. Замена второго раствора

    cell?.selectionStyle = UITableViewCellSelectionStyle.None
  3. Замена третьего решения

    self.tableView.userInteractionEnabled = false
Арун Гупта
источник
19

Попробуйте набрать:

cell.selected = NO;

Это отменит ваш ряд, когда это необходимо.

В Swift3 ...

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let r = indexPath.row
    print("clicked .. \(r)")
    tableView.cellForRow(at: indexPath)?.setSelected(false, animated: true)
}
Денис Кутлубаев
источник
14

Я тоже с этим боролся, контролируя UITableViewCellзапрет на использование userInteractionEnabledсобственности. У меня есть статическая таблица с 3 ячейками для настроек, 2 с датами, 1 с переключателем вкл / выкл. После игры в Storyboard / IB мне удалось сделать нижнюю одну невыбираемой, но при нажатии на нее выбор из одной из верхних строк исчезает. Вот WIP-изображение моих настроек UITableView:

Настройки UITableView

Если коснуться 3-го ряда, то ничего не произойдет, выбор останется на втором ряду. Функциональность практически является копией экрана выбора времени добавления приложения Apple Calendar.

Код на удивление совместим, вплоть до IOS2 = /:

- (NSIndexPath *)tableView: (UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 2) {
        return nil;
    }
    return indexPath;
}

Это работает в сочетании с установкой стиля выделения на none, поэтому ячейка не мерцает при событиях касания

Ярек Т
источник
11

Мы можем написать код, как

 cell.selectionStyle = UITableViewCellSelectionStyleNone;

но когда у нас есть пользовательская ячейка Xib над строкой, выдают предупреждение в то время

пользовательская ячейка XIB

нам нужно установить стиль выбора None от разработчика интерфейса

iDhaval
источник
11

Вы просто должны поместить этот код в cellForRowAtIndexPath

Чтобы отключить свойство выбора ячейки: (При прикосновении к ячейке).

cell.selectionStyle = UITableViewCellSelectionStyle.None
Гаурав Патель
источник
Спасибо, у меня есть изображение в моей камере и ярлык над ней. Я установил фон метки, но каждый раз, когда я нажимал, фон исчезал, это решало его.
Дарко
10

попробуй это

cell.selectionStyle = UITableViewCellSelectionStyleNone;

а также

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

и вы также можете установить стиль выбора с помощью Interface Builder.

v_1
источник
10

Я использую это, который работает для меня.

cell?.selectionStyle = UITableViewCellSelectionStyle.None
Приянка Гаутам
источник
7

Хотя это лучшее и самое простое решение, чтобы ряд не отображал выделение во время выделения.

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Я также хотел бы предложить, что иногда полезно кратко показать, что строка была выбрана, а затем отключить ее. Это предупреждает пользователей с подтверждением того, что они намеревались выбрать:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     [tableView deselectRowAtIndexPath:indexPath animated:NO];
...
}
Стив Барден
источник
7

Непосредственно отключить подсветку TableViewCell в раскадровке

введите описание изображения здесь

Камани Жасмин
источник
6

Чтобы отключить подсветку UItableviewcell

cell.selectionStyle = UITableViewCellSelectionStyleNone;

И не должен позволять пользователю взаимодействовать с клеткой.

cell.userInteractionEnabled = NO;
Sharme
источник
6

Вы также можете установить цвет фона на Очистить, чтобы достичь того же эффекта, что UITableViewCellSelectionStyleNoneи в случае, если вы не хотите / не можете использоватьUITableViewCellSelectionStyleNone .

Вы бы использовали код, подобный следующему:

UIView *backgroundColorView = [[UIView alloc] init];
backgroundColorView.backgroundColor = [UIColor clearColor];
backgroundColorView.layer.masksToBounds = YES;
[cell setSelectedBackgroundView: backgroundColorView];

Это может ухудшить вашу производительность, поскольку вы добавляете дополнительный цветной вид в каждую ячейку.

virindh
источник
6

Ты можешь использовать :

cell.selectionStyle = UITableViewCellSelectionStyleNone;

в ячейке для строки в методе индекса пути вашего UITableView.

Также вы можете использовать:

[tableView deselectRowAtIndexPath:indexPath animated:NO];

в табличном представлении сделайте выбор метода индекса.

Annu
источник
Это сейчас cell.selectionStyle = UITableViewCellSelectionStyle.noneв Свифте 3.
Дан
5

Вы можете использовать это

cell.selectionStyle = UITableViewCellSelectionStyleNone;
iEinstein
источник
5

Ты можешь использовать ....

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
Mak083
источник
5
cell.selectionStyle = UITableViewCellSelectionStyleNone;
iDeveloper
источник
5
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:NO];
[cell setHighlighted:NO animated:NO];

Удачного кодирования !!!

Ринку Садхвани
источник
5

Вы также можете сделать это из раскадровки. Щелкните ячейку табличного представления и в инспекторе атрибутов под ячейкой табличного представления измените раскрывающийся список рядом с «Выделением» на «Нет».

Синди
источник