Respostas:
No seu didSelectRowAtIndexPath
você precisa ligar deselectRowAtIndexPath
para desmarcar a célula.
Então, o que quer que você esteja fazendo, didSelectRowAtIndexPath
basta chamar deselectRowAtIndexPath
.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Do some stuff when the row is selected
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-deselectRowAtIndexPath:animated:
método em sua propriedade tableView partir -viewDidAppear
. No entanto, se você tiver uma exibição de tabela em uma subclasse UIViewController, deverá ligar -deselectRowAtIndexPath:animated:
de -viewDidAppear
si mesmo. :)
-viewWillAppear:
disso. Adicionando uma chamada para [super viewWillAppear:animated]
fazê-la funcionar novamente.
UITableViewController
's clearsSelectionOnViewWillAppear
propriedade é definida como YES
(que é o padrão), e você não ter impedido [super viewWillAppear]
de ser chamado.
A maneira mais limpa de fazer isso é no 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];
}
}
Dessa forma, você tem a animação de diminuir a seleção ao retornar ao controlador, como deveria ser.
Retirado de http://forums.macrumors.com/showthread.php?t=577677
Versão Swift
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
chamada pode retornar nula e deve ser verificada. A documentação declara : Um caminho de índice que identifica os índices de linha e seção da linha selecionada ou nulo se o caminho de índice for inválido.
Você subclasse -(void)viewWillAppear:(BOOL)animated
? O UITableViewCell selecionado não será desmarcado quando você não chamar [super viewWillAppear:animated];
seu método personalizado.
Para os usuários do Swift, adicione isso ao seu código:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
É a resposta de paulthenerd, exceto em Swift, em vez de Obj-C.
Atualizado com o Swift 4
Após algumas experiências, também baseadas em respostas anteriores, concluí que o melhor comportamento pode ser alcançado de duas maneiras: (quase idêntica na prática)
// 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)
}
}
Pessoalmente, estou adotando a primeira solução, porque é simplesmente mais concisa. Outra possibilidade, se você precisar de um pouco de animação ao retornar ao tableView, é usar 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)
}
}
Por fim, mas não menos importante, se você estiver usando um UITableViewController, também poderá tirar proveito da propriedade clearsSelectionOnViewWillAppear .
Para obter o comportamento que Kendall Helmstetter Gelner descreve em seu comentário, você provavelmente não deseja desmarcarRowAtIndexPath, mas sim a propriedade clearsSelectionOnViewWillAppear no seu controlador. Talvez isso tenha sido definido como SIM por acidente?
Veja o comentário no modelo padrão da Apple para novas subclasses UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
Eu estava recebendo esse problema também no meu aplicativo de pesquisa detalhada. Depois que um viewcontroller, que chamarei de VC, retorna após pressionar outro ViewController, a célula selecionada no VC permanece destacada. No meu aplicativo, eu criei o VC para lidar com o segundo nível (de três níveis) do meu detalhamento.
O problema no meu caso é que o VC era um UIViewController (que continha uma View que continha um TableView). Em vez disso, fiz do VC um UITableViewController (que continha um TableView). A classe UITableViewController manipula automaticamente o realce da célula da tabela após retornar de um push. A segunda resposta à postagem " Problema com deselectRowAtIndexPath em tableView " fornece uma resposta mais completa para esse problema.
O problema não ocorreu no controlador de visualização raiz, porque quando eu criei o aplicativo como um "Aplicativo baseado em navegação" no XCode, o controlador de visualização raiz resultante já havia sido criado para subclassificar UITableViewController.
Se nada disso funcionar para você, considere esta solução alternativa:
Use um desenrolar segue para chamar:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
Por que fazer isso? Principalmente se você estiver com problemas para executar o código de desmarcação na hora certa. Eu tive problemas para não funcionar no viewWillAppear, então o desenrolamento funcionou muito melhor.
Passos:
Escreva os seguimentos desenrolados (ou cole de cima) em seu 1º VC (aquele com a tabela)
Vá para o 2º VC. Arraste com a tecla Control pressionada no botão Cancelar / Concluído / Etc que você está usando para dispensar o VC e arraste para o ícone Sair na parte superior.
Selecione as etapas desenroladas que você criou na etapa 1
Boa sorte.
Estou usando o CoreData, então o código que funcionou para mim foi uma combinação de idéias de várias respostas, no Swift:
override func viewDidAppear(_ animated: Bool) {
if let testSelected = yourTable.indexPathForSelectedRow {
yourTable.deselectRow(at: testSelected, animated: true)
}
super.viewDidAppear(true)
}
Eu tenho o mesmo problema há muito tempo, por isso, caso alguém esteja lutando:
Dê uma olhada no seu -tableView: cellForRowAtIndexPath:
e veja se você está criando células ou usando um 'identificador de reutilização'. Nesse último caso, verifique se a sua tabela no IB possui uma célula com esse identificador. Se você não estiver usando um Identificador de reutilização, crie uma nova célula para cada linha.
Isso deve dar à sua tabela a 'linha selecionada fade selecionada' exibida.
Use este método na classe UITableViewCell
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
// Just comment This line of code
// [super setSelected:selected animated:animated];
}
Para Swift 3: eu preferiria usar no viewDidDisappear
Definir:-
var selectedIndexPath = IndexPath()
Em viewDidDisappear: -
override func viewDidDisappear(_ animated: Bool) {
yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}
Em didSelectRowAtIndexPath: -
func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
selectedIndexPath = indexPath
}
se a célula permanecer destacada depois de tocá-la, você poderá chamar o método UITabelView,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
`[tableView deselectRowAtIndexPath:indexPath animated:YES];`
}
Ou, você pode usar o seguinte método e modificá-lo de acordo com seus requisitos,
// 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
Eu tive esse mesmo problema e descobri que deixei uma chamada vazia para viewWillAppear na parte inferior do meu tableViewController. Depois de remover a função de substituição vazia, a linha não fica mais destacada ao retornar à visualização tableView.
função do problema
override func viewWillAppear(_ animated: Bool) {
// need to remove this function if not being used.
}
remover a função vazia resolveu meu problema.
deselectRowAtIndexPath
no meu viewDidAppear, se selecionar a linha abrir uma nova exibição.