На Android у меня есть представления элементов с потенциально большой шириной в списке с горизонтальной прокруткой. Представление загружает и рисует фрагменты «изображений» по мере того, как части представления становятся видимыми в списке. Это оптимизация, позволяющая избежать отрисовки всех изображений одновременно, так как это было бы расточительно и медленно. Нарисованный контент, по сути, представляет собой звуковую волну. Сделайте так, как все должно работать. Я не могу разделить фрагменты как отдельные элементы представления в списке. Эта стратегия отлично работает из-за того, как работает архитектура рисования Android.
Теперь я пытаюсь использовать аналогичный шаблон в iOS, но у меня возникли некоторые проблемы, и я не слишком уверен, как найти решение.
В iOS я использую UICollectionView
, который рисует ячейки большой ширины, и нам нужна такая же оптимизация загрузки и рисования только видимых фрагментов.
Решение 1.
Проверьте, какие части UIView
видны, и нарисуйте только эти видимые фрагменты. Проблема с этим решением заключается в том, что при прокрутке UICollectionView
UIView
не рисует следующие патроны, которые становятся видимыми. Вот примеры того, о чем я говорю.
UIView
загружает начальные фрагменты
Их можно увидеть по разным цветам фрагментов:
Прокрутите немного
Отображается черный цвет, а содержимое не загружается, потому что нет намека на то, что представление должно отрисовываться снова, поэтому мы не можем загрузить следующий видимый фрагмент .
Решение 2.
Используйте пользовательский UIView
, поддерживаемый CATiledLayer
. Это работает идеально, потому что он рисует плитки, когда они становятся видимыми при прокрутке UICollectionView
.
Проблема в том, что рисование происходит в фоновом потоке или в следующем цикле рисования, если определено shouldDrawOnMainThread
. Это вызывает проблемы, когда изменяется размер UIView
или срабатывает моя внутренняя логика масштабирования. Все меняется, потому что цикл рисования не синхронизирован с изменением размера вида.
Итак, как я могу получить уведомление, как CATiledLayer
, что часть становится видимой, и я могу нормально рисовать, как CALayer
с поддержкой UIView
?
ОБНОВЛЕНИЕ 1
Я рассматриваю возможность использования preferredLayoutAttributesFittingAttributes
как способа проверить, нужно ли рисовать новый фрагмент. Это вызывается каждый раз, когда ячейка перемещается в новую позицию из-за прокрутки. Надеюсь, это не плохая идея. :)
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
ОБНОВЛЕНИЕ 2
После долгих испытаний и экспериментов. Использование решения 1 не вариант. Когда UIView
достигает огромной ширины, использование памяти выходит за пределы крыши, в то время как при использовании CATiledLayer
использование памяти минимально, как я и ожидал. :/
func draw(_ rect: CGRect)
? - person MichaelV   schedule 28.02.2018func setNeedsDisplay(CGRect)
? Вы можете указать дополнительный флаг для рисования только тогда, когда вас просят нарисовать конкретный прямоугольник, и ничего не рисовать, когда флаг опущен. - person MichaelV   schedule 05.03.2018