Подтвердить что ты не робот

UICollectionview Скроллинг при загрузке ячеек

У меня есть галерея в моем приложении, использующая UICollectionView. Ячейки имеют размер приблизительно 70,70. Я использую ALAssets из ALAssetLibrary в галерее, которую я сохранил в списке.

Я использую обычный шаблон для заполнения ячеек:

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{

  mycell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  mycell.imageView.image = [[UIImage imageWithCGImage:[alassetList objectAtIndex:indexpath.row] thumbnail]];
  return mycell;
}

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

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

Теперь я подозреваю, что это может быть что-то в UICollectionViewCell prepareForReuse, которое может поддерживать метод dequeueReusableCellWithReuseIdentifier, но используя инструменты, которые я не смог найти.

Любая другая вещь, которая может быть причиной этого? Есть ли "более быстрый" способ для более быстрого создания UICollectionViewCell или dequeue?

4b9b3361

Ответ 1

Поэтому любой, кто имеет проблемы с прокруткой, должен this

добавить эти 2 строки после вашего удаления

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

Ответ 2

Я бы предположил, что "choppyness" исходит из распределения UIImage, а не с помощью метода dequeueReusableCellWithReuseIdentifier. Я бы попытался сделать выделение изображения в фоновом потоке и посмотреть, делает ли это что-то более маслянистым.

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
  mycell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
     // Load image on a non-ui-blocking thread
    UIImage *image = [[UIImage imageWithCGImage:[alassetList objectAtIndex:indexpath.row] thumbnail]];

    dispatch_sync(dispatch_get_main_queue(), ^(void) {
        // Assign image back on the main thread
        mycell.imageView.image = image;
    });
  });

  return mycell;
}

Более подробную информацию можно найти здесь: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html

Ответ 3

Загрузите изображения с помощью NSURLConnection sendAsynchronousRequest:queue:completionHandler:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    [cell.imageView setImage:[UIImage imageWithData:data]];
}];

Ответ 4

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

Ответ 5

У меня были проблемы с прокруткой UICollectionView.

Что работало (почти) как прелесть для меня: я заполнил ячейки с помощью png thumbnails 90x90. Я говорю почти потому, что первый полный свиток не настолько гладкий, но никогда больше не разбился...

В моем случае размер ячейки 90х90.

Раньше у меня было много оригинальных размеров png, и это было очень прерывисто, когда первоначальный размер png был больше ~ 1000x1000 (много сбоев при первом прокрутке).

Итак, я выбираю 90x90 (или тому подобное) на UICollectionView и показываю оригинальные png (независимо от размера). Надеюсь, это поможет другим.

Ответ 6

Если кто-то использует PhImageManager, выключение синхронного решения проблемы. (deliveryMode =.FastFormat также может дать дополнительное повышение производительности, но компромисс - это миниатюра будет более низкого качества)

    let option = PHImageRequestOptions()
    option.deliveryMode = .Opportunistic
    option.synchronous = false
    PHImageManager().requestImageForAsset(phAsset, targetSize: CGSizeMake(2048, 2048), contentMode: .AspectFit, options: option, resultHandler: { (image, objects) in
        self.imageView.image = image!
    })

Ответ 7

Я поделюсь своим опытом работы с коллекцией просмотров.

Swift 5

Если вы используете iOS 10+, производительность уже должна быть выше, чем в предыдущих версиях iOS. Я настоятельно рекомендую вам посмотреть это видео WWDC - Что нового в UICollectionView в iOS 10

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

  • Сначала убедитесь, что ваш collectionView соответствует делегату,

    yourCollectionView.prefetchDataSource = self
    
  • Затем просто реализуйте делегат предварительной выборки,

    extension YourViewController: UICollectionViewDataSourcePrefetching {
        func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
            // You could do further optimizations here.
        }
    }