UICollectionView не создает новую ячейку, если ячейка показана с использованием (indexPath.item % n == 0). Он не создает новую ячейку для кратных числу

#ios #swift #uicollectionview

#iOS #swift #uicollectionview

Вопрос:

Я использую это условие для создания определенных ячеек UICollectionViewCells.

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if(indexPath.item % 3 == 0){//multiples of 3
        let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "Cell1id", for: indexPath) as! Cell1
        cell.backgroundColor = .white

        if(cell.wasCreated){
            cell.cellLabel.text = "Cell(1) (indexPath.item) was created before."
        }
        else{
            cell.cellLabel.text = "Creating cell(1) (indexPath.item) first time."
            cell.wasCreated = true
        }

        return cell
    }
    else{
        let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "Cell2id", for: indexPath) as! Cell2
        cell.backgroundColor = .gray

        if(cell.wasCreated){
            cell.cellLabel.text = "Cell(2) (indexPath.item) was created before."
        }
        else{
            cell.cellLabel.text = "Creating cell(2) (indexPath.item) first time."
            cell.wasCreated = true
        }

        return cell
    }
}//end cellForItemAt
  

Здесь ‘wasCreated’ — это переменная внутри ячейки, которую я использую, чтобы проверить, создается ли ячейка в первый раз, если она задана мной wasCreated = true и это должно быть сделано в первый раз для каждой ячейки, но это не так.
Условие таково: если indexPath.item значение кратно 3, удалите ячейку 1, в противном случае ячейку 2.
Обычно, когда ячейка должна отображаться в первый раз, вызывается метод init() ячейки, но в этом случае он не вызывается, и более старая ячейка по какой-то причине удаляется.
Я понятия не имею, почему это происходит.

Я загрузил пример проекта, который воспроизводит проблему. Вот ссылка:https://github.com/AfnanAhmadiOSDev/IndexMultiplesTest.git

Комментарии:

1. Пожалуйста, отредактируйте свой вопрос, чтобы включить соответствующий код. Однако следует отметить, что это нормально для повторного использования ячеек. Вы не должны полагаться на инициализатор для настройки вашей ячейки. Вы можете использовать prepareForReuse в классе cell или настроить свою ячейку в cellForRow(at:)

2. Я не полагаюсь на инициализатор. Моя проблема в том, что инициализатор должен вызываться всякий раз, когда ячейка должна отображаться в первый раз, но это не так.

3. Что вы имеете в виду «в первый раз». Вы имеете в виду первый раз, когда отображается данное indexPath.item значение? Если да, то нет, это не так, как это работает. Ячейки используются повторно — Обратите внимание на название функции dequeueReusableCell Многократное использование

4. инициализация запускается каждый раз при выходе из очереди

5. Вы не поняли мою точку зрения. Хорошо, допустим, если у меня есть переменная с именем ‘wasCreated’ внутри ячейки, для которой по умолчанию установлено значение ‘false’. Теперь при удалении ячейки из очереди я проверяю, является ли эта переменная ‘true’, я устанавливаю для нее значение false. Этот сценарий должен сработать один раз для каждой ячейки, и при повторном использовании ячейки должно быть возвращено значение для этой ячейки ‘wasCreated’. Но в моем случае это не так. Не могли бы вы хотя бы раз попробовать демо-проект, который я прикрепил, а затем высказать свое мнение.

Ответ №1:

Описанное вами поведение является ожидаемым. Чтобы уменьшить использование памяти, ячейки используются повторно при прокрутке представления коллекции.

При вызове dequeueReusableCell UIKit проверяет, есть ли ячейка с запрошенным идентификатором, которая переместилась за пределы экрана и, следовательно, подходит для повторного использования. Если есть, то возвращается эта ячейка. В этом случае init не будет вызван. Если подходящей ячейки нет, то возвращается новый экземпляр ячейки, который init будет вызван.

При запуске вашего кода вы увидите, что сначала создаются ячейки, но после прокрутки вверх и вниз достаточно для создания достаточно большого пула повторного использования ячеек, ячейки используются повторно, и новые ячейки не создаются.

Повторное использование ячейки не зависит от того, IndexPath для чего ячейка использовалась ранее.

Комментарии:

1. ДА. Она ведет себя точно так, как я ожидал и как я описал в своем ответе.

2. Я не понимаю, какой вывод вы ожидаете увидеть? Вы ожидаете видеть постоянные ячейки «в первый раз» при прокрутке?

3. Нет. Я понимаю концепцию повторного использования. Ячейка с индексом 6 должна иметь значение ‘wasCreated’ как false по умолчанию при первом прокручивании до. Я знаю, что она повторно используется после ее отображения. Но даже при первом прокручивании значение ‘WASC Created’ равно true.

4. На самом деле это зависит от устройства, на котором вы его запускаете. На iPhone 5 вы увидите, что ячейка 6 является первой ячейкой, которая используется повторно. На iPhone XR ячейка 9 является первой, которая используется повторно. UIKit управляет размером пула повторного использования, чтобы сбалансировать объем памяти и наличие достаточного количества ячеек «вне экрана» для обеспечения плавной прокрутки и минимизации вызовов cellForItemAt . Это поведение не задокументировано и является непрозрачным.

5. Разве ячейки не должны быть «повторно использованы» после того, как они были использованы?