Sobes.tech
Junior

Como resolver o problema de reutilização de células em tabelas ou coleções?

sobes.tech IA

Resposta da IA

O problema de reutilização de células (cell reuse) em UITableView e UICollectionView está relacionado com o fato de que, ao percorrer a tabela ou coleção, o sistema reutiliza as células que saíram da área visível para mostrar novo conteúdo. Se a célula não for preparada adequadamente antes do uso, ela pode exibir dados antigos ou um estado incorreto.

A solução consiste no seguinte:

  1. Registar a célula: Antes de usar a célula, é necessário registá-la para reutilização com um identificador específico.

    // Registo para UITableView
    tableView.register(MyCustomCell.self, forCellReuseIdentifier: "MyCellIdentifier")
    
    // Registo para UICollectionView
    collectionView.register(MyCustomCell.self, forCellWithReuseIdentifier: "MyCellIdentifier")
    

    Isto permite que o sistema gerencie eficientemente o grupo de células reutilizáveis.

  2. Obter a célula reutilizável: Nos métodos tableView(_:cellForRowAt:) ou collectionView(_:cellForItemAt:), deve solicitar a célula reutilizável pelo identificador registado.

    // Para UITableView
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "MyCellIdentifier", for: indexPath) as? MyCustomCell else {
        fatalError("Falha ao obter MyCustomCell") // Uso de obtenção garantida com verificação de tipo
    }
    
    // Para UICollectionView
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCellIdentifier", for: indexPath) as? MyCustomCell else {
        fatalError("Falha ao obter MyCustomCell") // Uso de obtenção garantida com verificação de tipo
    }
    

    Os métodos dequeueReusableCell(withIdentifier:for:) ou dequeueReusableCell(withReuseIdentifier:for:) retornam ou uma célula existente do pool ou criam uma nova se o pool estiver vazio.

  3. Configurar a célula: Após obter a célula, deve definir os dados corretos para o indexPath atual (índice de linha/elemento). Isto é fundamental para resolver o problema de reutilização.

    // No método cellForRowAt ou cellForItemAt
    let data = dataArray[indexPath.row] // Exemplo de obtenção de dados do array
    cell.configure(with: data) // Chamada ao método de configuração da célula com os dados necessários
    
  4. O método prepareForReuse(): A sobreposição do método prepareForReuse() na classe personalizada da célula permite limpar ou redefinir o estado da célula antes de ela ser adicionada ao pool para reutilização. Isto é útil para limpar imagens, estados de interruptores, cancelar operações assíncronas, etc.

    // Dentro da classe MyCustomCell
    override func prepareForReuse() {
        super.prepareForReuse()
        // Limpar elementos UI
        imageView.image = nil
        titleLabel.text = nil
        // Cancelar tarefas assíncronas (por exemplo, carregamento de imagem)
        cancelAsyncTask()
        // Redefinir estados (por exemplo, seleção)
        someSwitch.isOn = false
    }
    

    Isto garante que, na próxima utilização, a célula comece de um estado limpo, sem herdar dados da visualização anterior.

É sempre importante configurar todos os aspetos da célula (campos de texto, imagens, cores, estado selecionado, etc.) com base nos dados do indexPath atual, e não confiar no estado anterior da célula reutilizada.