Como posso desativar a seleção UITableView?

1193

Quando você toca em uma linha em a UITableView, a linha é destacada e selecionada. É possível desativar isso para que tocar em uma linha não funcione?

DavidM
fonte
17
A pergunta original tem um título incorreto. O desejo do OP é basicamente desabilitar selectione, highlightingé claro, fica desabilitado com isso. Muitas respostas votadas explicam como disable selectione não abordam a desativação highlighting. Para desativar somente destacando o uso cell.selectionStyle = .Noneou ir parastoryboard / cell / Selection = None
Andrej
Atualize o título ou a publicação. Estou confuso. E com base nessa pergunta, não tenho idéia do que as respostas fornecidas devem fazer.
Daniel Springer

Respostas:

604

Para mim, o seguinte funcionou bem:

tableView.allowsSelection = false

Isso significa que didSelectRowAt#simplesmente não funcionará. Ou seja, tocar em uma linha da mesa, como tal, não fará absolutamente nada. (E, portanto, obviamente, nunca haverá uma animação selecionada.)

(Observe que, se nas células você tiver UIButtonou quaisquer outros controles, é claro que esses controles ainda funcionarão. Quaisquer controles que você possua na célula da tabela , não têm nenhuma relação com a capacidade do UITableView de permitir que você "selecione uma linha" usando didSelectRowAt#.)

Outro ponto a ser observado é o seguinte: Isso não funciona quando UITableViewestá no modo de edição. Para restringir a seleção de células no modo de edição, use o código abaixo:

tableView.allowsSelectionDuringEditing = false 
Let's_Create
fonte
6
isso finalmente funcionou para mim, tentei usar cell.selectionStyle = UITableViewCellSelectionStyleNone; mas não funcionou. Uma coisa a observar: deve ser: tableView.allowsSelection = NO; não é falso.
Tony.tc.leung
6
Eu acho que é a melhor opção. Os botões nas células estão ativos com isso, mas o texto não está ativo.
Fahim Parkar
513
Como esta é a resposta aceita e tem tantos votos positivos? Não responde a pergunta de todo! Você precisa definir a selectionStylepropriedade na célula: cell.selectionStyle = UITableViewCellSelectionStyle.Noneem Swift ou cell.selectionStyle = UITableViewCellSelectionStyleNoneem Objective-C.
Nodebase 23/09/15
5
Isso funciona para mim em rápida 2.tableView.allowSelection = false
Khanad
15
Existem algumas maneiras de fazer isso, dependendo do que é desejado. Nenhum estilo de seleção e nenhuma seleção podem funcionar ou podem falhar. Aqui está um exemplo. Se você deseja selecionar a célula e precisar tableViewDidSelectRowAtIndexPathchamar, cell.selectionStyle = .Noneé desejado. Se você não deseja ou não deseja que a função delegada seja chamada (por exemplo, ter um campo de texto em uma tabela tableViewCell), tableView.allowsSelection = falsetudo bem.
Made2k
1964

Tudo que você precisa fazer é definir o estilo de seleção na UITableViewCellinstância usando:

Objetivo-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

ou

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Swift 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None

Swift 3 e 4.x:

cell.selectionStyle = .none

Além disso, certifique-se de não implementar -tableView:didSelectRowAtIndexPath:na sua exibição de tabela delegar ou excluir explicitamente as células que você deseja que não tenham nenhuma ação se implementá-la.

Mais informações aqui e aqui

Martin Gordon
fonte
122
@ Tony É uma má idéia se você tiver um UITextField dentro da célula.
Aniruddh Joshi
73
@TonyMillion também é uma má ideia se você deseja usar controles de edição incorporados, como deslizar para excluir. Se você definir userInteractionEnabled como NO, o botão excluir não responderá aos eventos de toque do usuário.
Carlos P
47
atrasado para este encadeamento, mas em vez de userInteraction, use cell.allowsSelection. Isso interrompe os métodos de interação da célula, mas não bloqueia o material de resposta regular do UIView.
22712 Chris C #
4
Setting cell.userInteractionEnable = No não para de disparar um didSelectRowAtIndexPath.
user4951
25
Votarei a resposta, mas, para ficar claro, o OP pediu apenas para desativar o "destaque", não para desativar a interação de célula inteira, portanto todos esses comentários são offtopic.
Frederic Yesid Peña Sánchez 02/04
353

Como li este post recentemente e me ajudou, eu queria postar outra resposta para consolidar todas as respostas (para a posteridade).



Portanto, existem 5 respostas diferentes, dependendo da lógica e / ou resultado desejados:

1.Para desativar o realce azul sem alterar nenhuma outra interação da célula:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Eu uso isso quando tenho um UIButton - ou algum outro controle - hospedado em um UITableViewCell e quero que o usuário possa interagir com os controles, mas não com a própria célula.

NOTA : Como Tony Million observou acima, isso NÃO impedetableView:didSelectRowAtIndexPath:. Eu contigo isso com simples declarações "if", na maioria das vezes testando a seção e evitando ações para uma seção específica.

Outra maneira que pensei em testar o toque de uma célula como esta é:

- (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.Para fazer isso em uma tabela inteira, você pode aplicar a solução acima a cada célula da tabela, mas também pode fazer isso:

[tableView setAllowsSelection:NO];

Nos meus testes, isso ainda permite que os controles internos UITableViewCellsejam interativos.


3.Para tornar uma célula "somente leitura", você pode simplesmente fazer o seguinte:

[cell setUserInteractionEnabled:NO];



4.Para tornar uma tabela inteira "somente leitura"

[tableView setUserInteractionEnabled:NO];



5.Para determinar rapidamente se deve destacar uma célula (que de acordo com esta resposta inclui implicitamente a seleção), você pode implementar o seguinte UITableViewDelegatemétodo de protocolo:

- (BOOL)tableView:(UITableView *)tableView 
   shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
mbm29414
fonte
3
Se você carregar o design da célula a partir de uma ponta, a caixa de seleção (no IB) funcionará perfeitamente para o número 3 (e nas tabelas do número 4). Para # 4 vs # 2, a diferença é se os controles dentro da célula serão ou não interativos?
lilbyrdie
4
Sim. Se você deseja desativar a seleção, mas permitir que UIButtons, etc ... continuem a oferecer suporte à interação do usuário, use # 2. Se você deseja uma célula completamente somente leitura, use # 4. Claro, por que você teria tudo menos UIViews ou UILabels em uma célula não interativa está além de mim. Talvez alguém queira desativar toda a interação enquanto outra coisa está ocorrendo.
mbm29414
8
# 4 é uma idéia terrível, fazendo isso também irá desativar a rolagem na vista da tabela
simon
4
@ Simon Na verdade, não é uma péssima idéia; é uma opção que pode ou não ser uma boa opção, dependendo de suas circunstâncias. Além disso, o nº 4 desativa a rolagem do USUÁRIO; você ainda pode implementar o seu próprio, se necessário. Concordo que # 4 não é muito útil, mas não é uma péssima ideia.
mbm29414
3
Para completar, você pode adicionar uma mensagem para tableView:shouldHighlightRowAtIndexPath:, que geralmente é (nem sempre), minha abordagem preferida.
21915 Benjohn
82

Para resumir o que acredito serem as respostas corretas com base em minha própria experiência na implementação disso:

Se você deseja desativar a seleção para apenas algumas das células, use:

cell.userInteractionEnabled = NO;

Além de impedir a seleção, isso também impede que tableView: didSelectRowAtIndexPath: seja chamado pelas células que o definiram. (Obrigado a Tony Million por esta resposta, obrigado!)

Se você possui botões nas células que precisam ser clicados, é necessário:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

e você também precisa ignorar todos os cliques na célula - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath.

Se você deseja desativar a seleção para toda a tabela, use:

tableView.allowsSelection = NO;

(Crédito a Paulo De Barros, obrigado!)

JosephH
fonte
what Se tivermos um botão em nosso celular?
Umair Afzal 07/11
56

A partir do iOS 6.0, UITableViewDelegatetem tableView:shouldHighlightRowAtIndexPath:. (Leia sobre isso na documentação do iOS .)

Esse método permite que você marque linhas específicas como não destacáveis ​​(e implicitamente, não selecionáveis) sem precisar alterar o estilo de seleção de uma célula, interferindo no tratamento de eventos da célula userInteractionEnabled = NOou em qualquer outra técnica documentada aqui.

cbowns
fonte
2
Tropecei nessa discussão e fiquei chocado ao ver tantas outras respostas antes desta. Este é sem dúvida o caminho correto.
Beebcon
2
Esta é realmente a resposta correta e única que deve ser considerada. Qualquer outra coisa mencionando userInteraction está completamente incorreta.
mattyohe
50

Você também pode desativar a seleção de linhas no próprio construtor de interfaces, escolhendo NoSelectionentre a selectionopção (de UITableView Properties) no painel do inspetor, conforme mostrado na imagem abaixo

Inspetor UITableView

vignesh kumar
fonte
2
Melhor solução IMHO
Itai Spector
Costumo usar esta solução
Evsenev
46

SOLUÇÃO FIXA PARA SWIFT 3

cell.selectionStyle = .none
MANISH PATHAK
fonte
36

Em seu UITableViewCell's XIB no atributo de valor Inspector conjunto de Selectionpara None.

insira a descrição da imagem aqui

Zaid Pathan
fonte
Isso é exatamente o que eu precisava. Eu ainda queria a notificação didSelect ... mas sem a indicação visível da seleção. Obrigado!
Timothy Tripp
Fico feliz que ajudou! :)
Zaid Pathan
35

Se você deseja que a seleção pisque apenas, não permaneça no estado selecionado, você pode chamar, em

didSelectRowAtIndexPath

Os seguintes

[tableView deselectRowAtIndexPath:indexPath animated:YES];

para piscar o estado selecionado e reverter.

Chris Fox
fonte
3
Com essa abordagem, a linha é destacada instantaneamente e desaparece em meio segundo. É assim que a Apple estiliza seus menus Configurações, para que pareça bom para mim.
VinceFior
34

Caso alguém precise responder pelo Swift :

cell.selectionStyle = .None
Aks
fonte
1
também podemos usar esse cell.selectionStyle = UITableViewCellSelectionStyle.None
bably
29

É isso que eu uso, ao cellForRowAtIndexPathescrever este código .:

cell.selectionStyle = UITableViewCellSelectionStyleNone;
Ahsan Ebrahim
fonte
28

No UITableViewDelegateprotocolo, você pode usar o método willSelectRowAtIndexPath e, return nilse não desejar, a linha selecionada.

Da mesma maneira, você pode usar o willDeselectRowAtIndexPathmétodo e, return nilse não desejar, desmarcar a linha.

user41806
fonte
5
Não gosto desse método porque ele ainda mostra a célula em seu estado realçado até o retoque.
22610 kbanman
2
que é exatamente por isso que eu gosto :-)
Joris Weimar
24

1 - Tudo o que você precisa fazer é definir o estilo de seleção naUITableViewCell instância usando:


Objetivo-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

ou

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];


Swift 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None


Swift 3:

cell.selectionStyle = .none


2 - Não implemente - tableView:didSelectRowAtIndexPath:na exibição da tabela delegateou exclua explicitamente as células que você deseja que não executem nenhuma ação se você implementá-la.

3 - Além disso, você também pode fazer isso no storyboard. Clique na célula de exibição de tabela e, no inspetor de atributos, em Célula de exibição de tabela, altere a lista suspensa ao lado de Seleção para Nenhum.


4 - Você pode desativar o destaque da célula da tabela usando o código abaixo no (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
fonte
20

Objetivo-C:

  1. Abaixo do trecho, desative o destaque, mas também desative a chamada para didSelectRowAtIndexPath. Portanto, se você não estiver implementando didSelectRowAtIndexPath, use o método abaixo. Isso deve ser adicionado quando você estiver criando a tabela. Isso funcionará nos botões e UITextFielddentro da célula.

    self.tableView.allowsSelection = NO;
  2. Abaixo do trecho, desative o destaque e não desative a chamada para didSelectRowAtIndexPath. Defina o estilo de seleção da célula como Nenhum emcellForRowAtIndexPath

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
  3. O snippet abaixo desativa tudo na célula. Isso irá desativar a interação com buttons, textfields:

    self.tableView.userInteractionEnabled = false;

Rápido:

Abaixo estão o Swiftequivalente das Objective-Csoluções acima :

  1. Substituição da primeira solução

    self.tableView.allowsSelection = false
  2. Substituição da segunda solução

    cell?.selectionStyle = UITableViewCellSelectionStyle.None
  3. Substituição da Terceira Solução

    self.tableView.userInteractionEnabled = false
Arun Gupta
fonte
19

Tente digitar:

cell.selected = NO;

Desmarcará sua linha quando necessário.

Em Swift3 ...

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let r = indexPath.row
    print("clicked .. \(r)")
    tableView.cellForRow(at: indexPath)?.setSelected(false, animated: true)
}
Denis Kutlubaev
fonte
14

Também tenho lutado com isso muito profusamente, tendo um controle na minha UITableViewCellproibição do uso de userInteractionEnabledpropriedades. Eu tenho uma tabela estática de 3 células para configurações, 2 com datas, 1 com um botão liga / desliga. Depois de brincar no Storyboard / IB, consegui tornar a parte inferior não selecionável, mas quando você toca nela, a seleção de uma das linhas superiores desaparece. Aqui está uma imagem WIP das minhas configurações UITableView:

Configurações UITableView

Se você tocar na terceira linha, nada acontecerá, a seleção permanecerá na segunda linha. A funcionalidade é praticamente uma cópia da tela de seleção do horário do evento do aplicativo Calendário da Apple.

O código é surpreendentemente compatível, até o IOS2 = /:

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

Isso funciona em conjunto com a definição do estilo de seleção como nenhum, para que a célula não pisque nos eventos de toque para baixo

Yarek T
fonte
11

Podemos escrever código como

 cell.selectionStyle = UITableViewCellSelectionStyleNone;

mas quando tivermos a célula personalizada xib acima da linha, avise nesse momento para

célula personalizada xib

precisamos definir o estilo de seleção None no construtor de interface

iDhaval
fonte
11

Você só precisa colocar esse código em cellForRowAtIndexPath

Para desativar a propriedade de seleção da célula: (Ao tocar na célula).

cell.selectionStyle = UITableViewCellSelectionStyle.None
Gaurav Patel
fonte
Obrigado, tenho uma imagem no meu celular e uma etiqueta acima. Eu configurei o plano de fundo do rótulo, mas toda vez que eu clicasse no plano desapareceria, isso o solucionaria.
Darko
10

tente isso

cell.selectionStyle = UITableViewCellSelectionStyleNone;

e

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

e você também pode definir o estilo de seleção usando o interfacebuilder.

v_1
fonte
10

Estou usando isso, o que funciona para mim.

cell?.selectionStyle = UITableViewCellSelectionStyle.None
priyanka gautam
fonte
7

Embora essa seja a melhor e mais fácil solução para impedir que uma linha mostre o destaque durante a seleção

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Gostaria de sugerir também que ocasionalmente seja útil mostrar brevemente que a linha foi selecionada e depois desativá-la. Isso alerta os usuários com uma confirmação do que eles pretendem selecionar:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     [tableView deselectRowAtIndexPath:indexPath animated:NO];
...
}
Steve Barden
fonte
7

Desativar diretamente o destaque do TableViewCell no storyboard

insira a descrição da imagem aqui

Kamani Jasmin
fonte
6

Para desativar o realce da célula UItableview

cell.selectionStyle = UITableViewCellSelectionStyleNone;

E não deve permitir que o usuário interaja com a célula.

cell.userInteractionEnabled = NO;
Sharme
fonte
6

Você também pode definir a cor de fundo como Limpar para obter o mesmo efeito UITableViewCellSelectionStyleNone, caso não queira / não possa usar UITableViewCellSelectionStyleNone.

Você usaria código como o seguinte:

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

Isso pode prejudicar seu desempenho, pois você adiciona uma exibição extra colorida a cada célula.

virindh
fonte
6

Você pode usar :

cell.selectionStyle = UITableViewCellSelectionStyleNone;

na célula para a linha no método do caminho do índice do seu UITableView.

Também você pode usar:

[tableView deselectRowAtIndexPath:indexPath animated:NO];

no modo de exibição de tableletrowatindexpath.

Annu
fonte
É agora cell.selectionStyle = UITableViewCellSelectionStyle.noneem Swift 3.
Dan
5

Você pode usar isso

cell.selectionStyle = UITableViewCellSelectionStyleNone;
iEinstein
fonte
5

Você pode usar ....

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
Mak083
fonte
5
cell.selectionStyle = UITableViewCellSelectionStyleNone;
iDeveloper
fonte
5
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:NO];
[cell setHighlighted:NO animated:NO];

Feliz codificação !!!

Rinku Sadhwani
fonte
5

Você também pode fazer isso no storyboard. Clique na célula de exibição de tabela e, no inspetor de atributos, em Célula de exibição de tabela, altere a lista suspensa ao lado de Seleção para Nenhum.

Cindy
fonte