UITableview: как отключить выделение для некоторых строк, но не других

Я показываю в группе tableview содержимое, анализируемое из XML. Я хочу отключить событие click на нем (я не должен был бы нажимать на него вообще). Таблица содержит две группы. Я хочу отключить выбор только для первой группы, но не для второй группы. Нажав первую строку второй группы navigates на мою трубку player view.

Как я могу выбрать только определенные группы или строки?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if(indexPath.section!=0)
    if(indexPath.row==0)    

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:tubeUrl]];   
}

Спасибо.

Ответ 1

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

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

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Чтобы включить возможность выбрать (нажать) ячейку: (касание ячейки)

// Default style
cell.selectionStyle = UITableViewCellSelectionStyleBlue;

// Gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;

Обратите внимание, что ячейка с selectionStyle = UITableViewCellSelectionStyleNone; все еще заставит пользовательский интерфейс вызывать didSelectRowAtIndexPath при прикосновении пользователя. Чтобы избежать этого, сделайте как предложено ниже и установите.

cell.userInteractionEnabled = NO;

вместо. Также обратите внимание, что вы можете установить cell.textLabel.enabled = NO; серым цветом

Ответ 2

Если вы хотите сделать строку (или подмножество строк), не выбирается, реализовать UITableViewDelegate метод -tableView:willSelectRowAtIndexPath: (также упоминаемый TechZen). Если indexPath должен быть выбираемым, верните nil, в противном случае верните indexPath. Чтобы получить поведение выбора по умолчанию, вы просто возвращаете indexPath переданный в ваш метод delegate, но вы также можете изменить выбор строки, возвращая другой indexPath.

пример:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // rows in section 0 should not be selectable
    if ( indexPath.section == 0 ) return nil;

    // first 3 rows in any section should not be selectable
    if ( indexPath.row <= 2 ) return nil;

    // By default, allow row to be selected
    return indexPath;
}

Ответ 3

Начиная с iOS 6, вы можете использовать

-tableView:shouldHighLightRowAtIndexPath:

Если вы вернетесь NO, он отключит выделение выделения и сцену, инициированную раскадрой, подключенную к этой ячейке.

Метод вызывается, когда прикосновение падает вниз. Возврат NO к этому сообщению останавливает процесс выбора и не приводит к тому, что текущая выбранная строка теряет свой выбранный вид, пока нажата кнопка.

Ссылка на протокол UITableViewDelegate

Ответ 4

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

В моем случае я представлял UISwitch в середине строки, и я хотел отключить выделение для остальной части строки (пустой), но не для коммутатора! Таким образом, надлежащим способом выполнения этого является метод

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

где утверждение формы

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

который просто подготавливает ячейку и не позволяет взаимодействовать с UISwitch.

Кроме того, используя метод

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

чтобы отменить выбор ячейки с помощью инструкции вида

[tableView deselectRowAtIndexPath:indexPath animated:NO];

по-прежнему показывает выбранную строку, когда пользователь нажимает на исходное содержимое элемента.

Просто мои два цента. Я уверен, что многие найдут это полезным.

Ответ 5

Вы выбрали выбор с помощью этих методов источника данных.

– tableView:willSelectRowAtIndexPath: 
– tableView:didSelectRowAtIndexPath: 
– tableView:willDeselectRowAtIndexPath: 
– tableView:didDeselectRowAtIndexPath:

В этих методах вы проверяете, является ли выбранная строка той, которую вы хотите выбрать. Если это так, предпримите действие, если нет, ничего не сделайте.

К сожалению, вы не можете отключить выбор только для одной секции. Это целый стол или ничего.

Однако вы можете установить для ячейки таблицы selectionStyle свойство UITableViewCellSelectionStyleNone. Я считаю, что это сделает выбор невидимым. В сочетании с вышеупомянутыми методами, которые должны сделать клетки выглядят полностью инертными с точки зрения пользователя.

Edit01:

Если у вас есть таблица, в которой выбираются только некоторые из строк, важно, чтобы ячейки выбранных строк визуально отличались от неизбираемых строк. Кнопка аксессуара chevron - это способ по умолчанию.

Однако вы это делаете, вы не хотите, чтобы ваши пользователи пытались выбрать строки и подумали, что приложение получило неправильное значение, потому что строка ничего не делает.

Ответ 6

Вам нужно сделать что-то вроде следующего, чтобы отключить выбор ячейки в методе cellForRowAtIndexPath:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];

Чтобы показать выделенную ячейку, добавьте следующее в метод tableView:WillDisplayCell:forRowAtIndexPath:

[cell setAlpha:0.5];

Один метод позволяет вам контролировать интерактивность, а другой позволяет вам контролировать внешний вид пользовательского интерфейса.

Ответ 7

Для Swift 4.0 например:

cell.isUserInteractionEnabled = false
cell.contentView.alpha = 0.5

Ответ 8

Чтобы остановить только выбранные ячейки, используйте:

cell.userInteractionEnabled = NO;

Помимо предотвращения выбора, это также останавливает tableView: didSelectRowAtIndexPath: вызывается для ячеек, которые он установил.

Ответ 9

Мое решение на основе модели данных:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
    return rowDetails.enabled ? indexPath : nil
}

func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
    let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
    return rowDetails.enabled
}

Ответ 10

Вы можете использовать метод tableView:willDisplayCell для выполнения всех видов настройки в tableViewCell.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
     [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
     [cell setUserInteractionEnabled:NO];

     if (indexPath.section == 1 && indexPath.row == 0)
     {
         [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
         [cell setUserInteractionEnabled:YES];
     }
} 

В этом вышеприведенном коде пользователь может выбрать только первую строку во втором разделе tableView. Остальные все строки не могут быть выбраны. Спасибо! ~

Ответ 11

Для Swift 4.0 это сделает свое дело. Он отключит ячейку в методе didSelectRowAtIndexPath, но при этом подпредставления будут активными.

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
         if (indexPath.row == clickableIndex ) { 
            return indexPath
         }else{
            return nil
        }
    }

Ответ 12

Для быстрого:

cell.selectionStyle = .None
cell.userInteractionEnabled = false

Ответ 13

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

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Важно: обратите внимание, что это только свойство стиля и фактически не отключает ячейку. Для этого вам нужно проверить selectionStyle в реализации делегирования didSelectRowAtIndexPath::

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if(cell.selectionStyle == UITableViewCellSelectionStyleNone) {
        return;
    }

    // do your cell selection handling here
}

Ответ 14

ПРОСТОЙ

Просто используйте cell.userInteractionEnabled = YES; для ячейки, если она может перемещаться, и cell.userInteractionEnabled = NO; в противном случае

Ответ 15

Мне нравится Брайан Чападос ответить выше. Однако это означает, что вы можете дублировать логику как в cellForRowAtIndexPath, так и в willSelectRowAtIndexPath, которая может легко выйти из синхронизации. Вместо того, чтобы дублировать логику, просто проверьте selectionStyle:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.selectionStyle == UITableViewCellSelectionStyleNone)
        return nil;

    else
        return indexPath;
}

Ответ 16

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

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
        return nil;
    }
    return indexPath;
}

Ответ 17

на Xcode 7 без кодирования вы можете просто сделать следующее:

В виде контура выберите "Показать таблицу". (Ячейка вложена под сценой Контроллер табличного представления > Контроллер табличного представления > Вид таблицы. Возможно, вам придется раскрыть эти объекты, чтобы увидеть ячейку представления таблицы)

В инспекторе атрибутов найдите поле с надписью "Выбор" и выберите "Нет". инспектор атрибутов С помощью этой опции ячейка не получит визуального выделения, когда пользователь удаляет ее.

Ответ 18

Внесите только метод tableView:willSelectRowAtIndexPath: в источнике данных для вашей таблицы. Если вы хотите, чтобы строка на пути выделилась, верните данный индекс. Если вы этого не сделаете, верните нуль.

Пример из моего приложения:

- (NSIndexPath *)tableView:(UITableView *)tableView
    willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MySelectableObj* obj = [self objectAtPath:indexPath];
    if(obj==nil) return nil;
    return indexPath;
}

Приятная вещь в том, что shouldPerformSegueWithIdentifier:sender: не будет вызываться, если указанный выше метод возвращает nil, хотя я повторяю тест выше только для полноты.

Ответ 19

Для Xcode 6.3:

 cell.selectionStyle = UITableViewCellSelectionStyle.None;

Ответ 20

Для меня было выполнено следующее:

tableView.allowsSelection = NO;

Ответ 21

Я согласен с ответом Брайана

если я сделаю

cell.isUserInteractionEnabled = false 

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

На другом сайте настройка

cell.selectionStyle = .none

вызовет метод didSelect, несмотря на отсутствие обновления цвета выделения.

Используя willSelectRow, я решил свою проблему. Пример:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {

    if indexPath.section == 0{

        if indexPath.row == 0{
            return nil
        }

    }
    else if indexPath.section == 1{

        if indexPath.row == 0{
            return nil
        }

    }

    return indexPath

}

Ответ 22

для swift 3.0 вы можете использовать нижеприведенный код, чтобы отключить взаимодействие пользователя с ячейкой UITableView

 cell.isUserInteractionEnabled = false