prepareLayout метод NSCollcectionViewLayout - PullRequest
0 голосов
/ 03 марта 2019

Мне трудно понять цель prepareLayout метода NSCollectionViewLayout.

В соответствии с официальной яблочной документацией написано

Во время процесса макета представление сбора вызывает несколько методов вашего объекта макета для сбора информации.В частности, он вызывает три очень важных метода, реализация которых определяет поведение основного макета.

  • Используйте метод prepareLayout для выполнения первоначальных расчетов макета.Эти вычисления обеспечивают основу для всего, что объект макета делает позже.

  • Используйте метод collectionViewContentSize, чтобы вернуть наименьший прямоугольник, который полностью охватывает все элементы в представлении коллекции.Используйте вычисления из вашего метода prepareLayout, чтобы указать этот прямоугольник.

  • Используйте layoutAttributesForElementsInRect: метод, чтобы вернуть атрибуты макета для всех элементов в указанном прямоугольнике.Представление коллекции, как правило, запрашивает только подмножество видимых элементов, но может включать элементы, которые находятся за пределами экрана.

Метод prepareLayout - это ваш шанс выполнить основные вычисления, связанные с процессом макета.Используйте этот метод для создания начального списка атрибутов макета для вашего контента.Например, используйте этот метод для вычисления прямоугольников рамки всех элементов в представлении коллекции.Выполнение всех этих вычислений заранее и кэширование полученных данных часто проще, чем попытка вычислить атрибуты для отдельных элементов позже.

В дополнение к layoutAttributesForElementsInRect: метод, представление коллекции может вызывать другие методы для извлечения атрибутов макетадля конкретных предметов.Выполняя ваши вычисления заранее, ваши реализации этих методов должны иметь возможность возвращать кэшированную информацию без необходимости сначала пересчитывать эту информацию.Единственный раз, когда ваш объект макета должен пересчитать свою информацию о макете, это когда ваше приложение делает макет недействительным.Например, вы можете сделать недействительным макет, когда пользователь вставляет или удаляет элементы.

Поэтому я наивно использовал это как руководство и переписал мою реализацию пользовательского макета.Я вычислил collectionViewContentSize и предварительно вычислил массив, используемый в этом методе

- (NSArray<__kindof NSCollectionViewLayoutAttributes *>*)layoutAttributesForElementsInRect:(NSRect)rect;

, так что во всех 3 обязательных методах я просто возвращаю кэшированные значения.И после этого внезапно мой collectionView стал очень запаздывающим.

Видимо, метод prepareLayout вызывается при каждой прокрутке.

Может кто-нибудь уточнить, что это значит.А может я ничего не понимаю?

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Обычно, если вы не хотите, чтобы prepare вызывался каждый раз, когда происходит событие прокрутки, это сохранить свойство экземпляра CGSize и реализовать shouldInvalidateLayout, чтобы он возвращал YES, только если размер новых границ отличаетсяиз сохраненного значения свойства CGSize.

Вот пример Swift, но я уверен, что вы можете перевести его в Objective-C:

var oldBoundsSize = CGSize.zero
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
    let ok = newBounds.size != self.oldBoundsSize
    if ok {
        self.oldBoundsSize = newBounds.size
    }
    return ok
}
0 голосов
/ 03 марта 2019

Так что это было мое плохо.Очевидно, если

- (BOOL)shouldInvalidateLayoutForBoundsChange:(NSRect)newBounds;

возвращает YES.Затем этот метод называется.Я только что изменил, что этот метод возвращает NO и метод prepareLayout был остановлен, вызывается все время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...