it-swarm.com.ru

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

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

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

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

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

Благодарю.

274
Warrior

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

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

cell.selectionStyle = UITableViewCellSelectionStyleNone;

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

// Default style
cell.selectionStyle = UITableViewCellSelectionStyleBlue;

// Gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;

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

cell.userInteractionEnabled = NO;

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

471
Pugal

Если вы хотите создать строку (или подмножество строк) без возможности выбора, внедрите метод 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;
}
338
Brian Chapados

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

-tableView:shouldHighLightRowAtIndexPath:

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

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

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

54
Keller

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

В моем случае я представлял UIS-переключатель в середине строки и хотел отключить выбор для остальной части строки (которая пуста), но не для переключателя! Правильный способ сделать это, следовательно, в методе

- (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];

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

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

16
MightyMouse

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

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

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

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

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

Edit01:

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

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

10
TechZen

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

cell.isUserInteractionEnabled = false
cell.contentView.alpha = 0.5
9
Alessandro Ornano

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

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

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

[cell setAlpha:0.5];

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

9
azfar

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

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
}
5
SoftDesigner

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

cell.userInteractionEnabled = NO;

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

5
JosephH

Вы можете использовать метод 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. Остальные все строки не могут быть выбраны. Спасибо! ~

4
Abdul Rahman

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

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

Для Свифта:

cell.selectionStyle = .None
cell.userInteractionEnabled = false
3
Esqarrouth

ПРОСТОЙ

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

1
Rick Royd Aban

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

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

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

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
}
1
pt2ph8

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

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

    else
        return indexPath;
}
1
Eric D'Souza

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

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

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

1
Tung Fam

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

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

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

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

0
user3821934

Для Xcode 6.3:

 cell.selectionStyle = UITableViewCellSelectionStyle.None;
0
uplearnedu.com

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

если я сделаю

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

}
0
Reimond Hill