Добейтесь плавной прокрутки для Photo Grid с тысячами изображений с диска
У меня есть PhotoGrid
с тремя фотографиями в каждом ряду, реализованные с использованием UITableView
,
У меня есть кэш в памяти (использующий NSCache), который вмещает 100 изображений, поэтому в один момент у меня будет не более 100 изображений в памяти, даже если у меня есть тысячи изображений на диске для отображения в Grid.
Все мои изображения 4KB-20KB JPEG.
Таким образом, благодаря этой инфраструктуре изображения постоянно загружаются и выгружаются из NSCache, когда пользователь прокручивает сетку фотографий. При нормальной прокрутке все выглядит хорошо, я получаю около 55-58 кадров в секунду.
Когда пользователь начинает прокручивать быстрее вперед и назад, у меня есть два случая:
Если я отделю задачу загрузки изображений от основного потока, я получаю отсутствующие изображения в сетке фотографий, потому что мои ячейки отображаются до того, как изображения будут считаны в память.
(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ UIImage *image = getImageFromCacheForImagePath:imagePath; dispatch_async(dispatch_get_main_queue(), ^{ cell.leftGridItem.imageView.image = image; }); }); }
Если у меня есть задача загрузки изображений в главном потоке, возникает заикание. Я получаю около 36-45 кадров в секунду.
(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UIImage *image = getImageFromCacheForImagePath:imagePath; cell.leftGridItem.imageView.image = image; }
getImageFromCacheForImagePath:imagePath
получает изображение сразу из NSCache, если оно существовало, если нет, изображение загружается из файла и устанавливается в NSCache для последующего использования, но я установил предел NSCache
до 100.
Вещи, которые я пробовал / подправил:
- избежать
clipsToBounds
для просмотра изображений сетки. - Загрузка изображений в фоновом потоке.
- Использование
NSOperation
Очереди. - Загрузка изображений партиями по 100 (работает, но с быстрой прокруткой, время загрузки изображения было отложено).
Я пытаюсь добиться того же ощущения, что и родное приложение Photos.
Ваши предложения приветствуются.
2 ответа
Я реализовал таблицу плавной прокрутки с более чем 700 изображениями. Ключом было не только загрузить изображения в фоновом режиме, но и изменить его размер в фоновом режиме, чтобы он идеально подходил для контейнера. Изменение размера - слишком сложная операция, чтобы сделать это в потоке пользовательского интерфейса.
Я также столкнулся с той же проблемой несколько дней назад, поэтому GitHub - лучшее место для поиска решений с открытым исходным кодом, поэтому попробуйте эти ссылки.
Проверьте PF-GridView или DTGridView.
также взгляните на AQGridView, Как написать пользовательский инструмент выбора изображений, такой как UIImagePicker,
Просто нужно сделать немного манипуляции в соответствии с нашими потребностями, и это работает как чемпион.