Sobes.tech
Junior

Kaip išspręsti langelių pakartotinio naudojimo problemą lentelėse ar kolekcijose?

sobes.tech AI

Atsakymas iš AI

Problema, susijusi su ląstelių pakartotiniu naudojimu UITableView ir UICollectionView, kyla dėl to, kad slinkimo metu sistema pakartotinai naudoja iš užmatomų sričių išėjusias ląsteles naujam turiniui rodyti. Jei ląstelės prieš naudojimą nėra tinkamai paruošiamos, ji gali rodyti senus duomenis arba netinkamą būseną.

Sprendimas yra šis:

  1. Ląstelės registravimas: Prieš naudojant ląstelę, ją reikia užregistruoti pakartotiniam naudojimui pagal tam tikrą identifikatorių.

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

    Tai leidžia sistemai efektyviai valdyti pakartotinai naudojamų ląstelių rezervuarą.

  2. Gauti pakartotinai naudojamą ląstelę: Metoduose tableView(_:cellForRowAt:) arba collectionView(_:cellForItemAt:) reikia užklausti pakartotinai naudojamą ląstelę pagal užregistruotą identifikatorių.

    // `UITableView`
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "MyCellIdentifier", for: indexPath) as? MyCustomCell else {
        fatalError("Nepavyko gauti `MyCustomCell`") // Garantinis tipų patikrinimas
    }
    
    // `UICollectionView`
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCellIdentifier", for: indexPath) as? MyCustomCell else {
        fatalError("Nepavyko gauti `MyCustomCell`") // Garantinis tipų patikrinimas
    }
    

    Metodai dequeueReusableCell(withIdentifier:for:) arba dequeueReusableCell(withReuseIdentifier:for:) arba grąžina esamą pakartotinai naudojamą ląstelę iš rezervuaro, arba sukuria naują, jei rezervuaras tuščias.

  3. Ląstelės konfigūracija: Po ląstelės gavimo būtina tinkamai nustatyti duomenis pagal dabartinį indexPath. Tai yra pagrindinis žingsnis sprendžiant pakartotinio naudojimo problemą.

    // `cellForRowAt` arba `cellForItemAt` metode
    let data = dataArray[indexPath.row] // Duomenų gavimas iš masyvo
    cell.configure(with: data) // Ląstelės konfigūracijos metodo iškvietimas
    
  4. prepareForReuse() metodas: Klasės ląstelėje perrašymas prepareForReuse() leidžia išvalyti arba atstatyti ląstelės būseną prieš ją įdedant į rezervuarą pakartotiniam naudojimui. Tai naudinga atlaisvinant vaizdus, perjungimo būsenas, atšaukiant asinchronines operacijas ir pan.

    // `MyCustomCell` klasėje
    override func prepareForReuse() {
        super.prepareForReuse()
        // UI elementų atstatymas
        imageView.image = nil
        titleLabel.text = nil
        // Asinchroninių užduočių atšaukimas
        cancelAsyncTask()
        // Būsenų atstatymas
        someSwitch.isOn = false
    }
    

    Tai užtikrina, kad kitą kartą naudojant ląstelė pradės nuo švarios būsenos, nesusijusios su ankstesniu rodymu.

Svarbu visada konfigūruoti visus ląstelės aspektus (teksto laukus, vaizdus, spalvas, pasirinktas būsenas ir pan.) remiantis dabartiniais duomenimis indexPath, o ne pasikliauti ankstesne pakartotinio naudojimo būsenos informacija.