28

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

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

-(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 им быстрее?

+1

Используя инструменты, вы запятнать вызов метода, который занимает слишком много времени? Например. 0.02 сек для повторного использования одной ячейки слишком много для плавной прокрутки. –

+0

Да. После этого я увидел, что метод [uicollectionview updatevisiblecellsnow] называется тоннами раз. В эту проблему попала эта проблема и попал на этот вопрос http://stackoverflow.com/questions/16336772/uicollectionview-performance-updatevisiblecellsnow. –

+0

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

ответ

89

Так кто-либо, имеющие проблемы прокрутки должны сделать this

добавить эти 2 строки после DEQUEUE

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

Извините, что мне делать? Ваша ссылка указывает на страницу с большим количеством контента. Должен ли я читать все это, если у меня есть ++ какая-либо проблема с прокруткой ++? Или просто, если она лаги? –

+0

Я не уверен, в чем проблема. Вы можете указать мне на свой вопрос, но в моем случае получается, что UICollectionView вызывал лаггию, и мой код действительно хорошо работал. В моем случае принудительное изменение уровня ячейки для растровой проблемы. В других случаях вы можете попытаться использовать Time Instument в XCode, чтобы понять медленность. Если это ваш код или какой-то системный код. –

+0

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

0

Я имел проблемы с UICollectionView прокрутки.

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

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

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

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

8

Загрузите изображения с помощью 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]]; 
}]; 
19

Я бы предположить «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

1

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

0

Если кто-то использует PhImageManager, то выключение синхронного решения проблемы. (доставкаMode =.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! 
    })