Sobes.tech
Junior

Cum se rezolvă problema reutilizării celulelor în tabele sau colecții?

sobes.tech AI

Răspuns de la AI

Problema reutilizării celulelor (cell reuse) în UITableView și UICollectionView este legat de faptul că, la derularea tabelului sau colecției, sistemul reutilizează celulele care au ieșit din zona vizibilă pentru a afișa conținut nou. Dacă celula nu este pregătită corespunzător înainte de utilizare, poate afișa date vechi sau o stare incorectă.

Soluția este următoarea:

  1. Înregistrarea celulei: Înainte de utilizare, celula trebuie înregistrată pentru reutilizare cu un identificator specific.

    // Înregistrare pentru UITableView
    tableView.register(MyCustomCell.self, forCellReuseIdentifier: "MyCellIdentifier")
    
    // Înregistrare pentru UICollectionView
    collectionView.register(MyCustomCell.self, forCellWithReuseIdentifier: "MyCellIdentifier")
    

    Acest lucru permite sistemului să gestioneze eficient pool-ul de celule reutilizabile.

  2. Obținerea celulei reutilizabile: În metodele tableView(_:cellForRowAt:) sau collectionView(_:cellForItemAt:), trebuie solicitată celula reutilizabilă după identificatorul înregistrat.

    // Pentru UITableView
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "MyCellIdentifier", for: indexPath) as? MyCustomCell else {
        fatalError("Nu s-a putut obține MyCustomCell") // Obținere garantată cu verificare de tip
    }
    
    // Pentru UICollectionView
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCellIdentifier", for: indexPath) as? MyCustomCell else {
        fatalError("Nu s-a putut obține MyCustomCell") // Obținere garantată cu verificare de tip
    }
    

    Metodele dequeueReusableCell(withIdentifier:for:) sau dequeueReusableCell(withReuseIdentifier:for:) returnează fie o celulă existentă din pool, fie creează una nouă dacă pool-ul este gol.

  3. Configurarea celulei: După obținerea celulei, trebuie setate datele corecte pentru indexPath curent (indicele rândului/elementului). Acesta este un pas esențial pentru rezolvarea problemei reutilizării.

    // În metoda cellForRowAt sau cellForItemAt
    let data = dataArray[indexPath.row] // Exemplu de obținere a datelor din array
    cell.configure(with: data) // Apelarea metodei de configurare a celulei cu datele necesare
    
  4. Metoda prepareForReuse(): Suprascrierea metodei prepareForReuse() în clasa personalizată a celulei permite curățarea sau resetarea stării celulei înainte de a fi adăugată în pool pentru reutilizare. Acest lucru este util pentru resetarea imaginilor, stărilor switch-urilor, anularea operațiilor asincrone etc.

    // În clasa MyCustomCell
    override func prepareForReuse() {
        super.prepareForReuse()
        // Resetarea elementelor UI
        imageView.image = nil
        titleLabel.text = nil
        // Anularea sarcinilor asincrone
        cancelAsyncTask()
        // Resetarea stărilor
        someSwitch.isOn = false
    }
    

    Acest lucru asigură că, la următoarea utilizare, celula va începe dintr-o stare curată, fără a moșteni datele din afișarea anterioară.

Este întotdeauna important să configurați toate aspectele celulei (câmpurile de text, imaginile, culorile, starea selectată etc.) pe baza datelor pentru indexPath curent, și să nu vă bazați pe starea anterioară a celulei reutilizate.