28

Mam galerię w mojej aplikacji z wykorzystaniem UICollectionView. Komórki mają rozmiar około 70,70. Używam ALAssets z galerii ALAssetLibrary w galerii, którą zapisałem na liście.UICollectionview Przewijanie przerywane podczas ładowania komórek

Używam zwykły wzorzec dla wypełniania komórek:

-(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; 
} 

Moja galeria jest przewijanie niepewny. Nie rozumiem, dlaczego tak jest. Próbowałem dodać NSCache do buforowania miniaturek (myślę, że może tworzenie obrazów było drogie), ale to nie pomogło w wydajności.

Spodziewam się, że interfejs użytkownika będzie równie maślany jak aplikacja giełdowa.

Podejrzewam, że może to być coś w UICollectionViewCell prepareForReuse, które może wstrzymywać metodę dequeueReusableCellWithReuseIdentifier, ale używając instrumentów, nie byłem w stanie tego znaleźć.

Czy może to być inna przyczyna? Czy istnieje "szybszy" sposób na szybsze przygotowanie modeli UICollectionViewCell lub dequeue?

+1

Za pomocą instrumentów zauważyłeś wywołanie metody, które zajęło zbyt dużo czasu? Na przykład. 0,02 s dla ponownego użycia jednej komórki to zbyt dużo dla płynnego przewijania. –

+0

Tak. Po zrobieniu tego zobaczyłem, że metoda [uicollectionview updatevisiblecellsnow] była wywoływana wiele razy. Google zgłosił ten problem i dostał się do tego pytania http://stackoverflow.com/questions/16336772/uicollectionview-performance-updatevisiblecellsnow. –

+0

Spróbuj przenieść niektóre funkcje związane z wyświetlaniem komórki do metody willDisplayCell widoku kolekcji, a inne do metody didEndDisplayingCell. –

Odpowiedz

89

więc każdy problemy przewijania powinna zrobić this

dodać te 2 linie po rozkolejkowania

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

Niestety, co powinienem zrobić? Twój link wskazuje na stronę z dużą ilością treści. Czy powinienem przeczytać to wszystko, jeśli mam + ++ przewijany problem? Lub po prostu jeśli jest opóźniony? –

+0

Nie jestem pewien, co jest dokładnie twój problem. Możesz wskazać mi na twoje pytanie, ale w moim przypadku okazuje się, że UICollectionView spowodował opóźnienie i mój kod faktycznie działał dobrze, w moim przypadku wymuszenie na warstwie komórek rastrowych rozwiązało problem.W innych przypadkach można spróbować użyć Time Instument w XCode, aby zrozumieć powolność.Jeśli to twój kod lub niektóre kod systemowy. –

+0

w skrócie, po prostu spróbuj dodać 2 linie, które zamieściłem do metody cellforitematindexpath po odczytywaniu komórki i zobacz, czy to pomaga. –

0

miałem problemy z UICollectionView przewijania.

Co zadziałało (prawie) jak dla mnie urok: zapełniłem komórki miniaturami png 90x90. Mówię prawie, ponieważ pierwszy kompletny zwój nie jest tak gładki, ale nigdy się nie rozbił ...

W moim przypadku rozmiar komórki wynosi 90x90.

Miałem wiele oryginalnych rozmiarów png przed, i było bardzo niepewnie, gdy png pierwotny rozmiar był większy niż ~ 1000x1000 (wiele awarii podczas pierwszego przewijania).

Wybieram 90x90 (lub temu podobne) na UICollectionView i wyświetlam oryginalny pngs (bez względu na rozmiar). Mam nadzieję, że to pomoże innym.

8

Załaduj swoje zdjęcia za pomocą NSURLConnection na 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

chciałbym przyjąć „choppyness” pochodzi z przydziału UIImage, nic nie metodą dequeueReusableCellWithReuseIdentifier. Spróbowałbym zrobić alokację obrazu na wątku tła i sprawdzić, czy to sprawia, że ​​rzeczy są trochę bardziej maślane.

-(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; 
} 

Więcej szczegółów można znaleźć tutaj: włączone https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html

1

Tick na klip subviews i nieprzezroczysta w atrybutach inspektora i zbesztać stronicowania.

0

Jeśli ktoś używa PhImageManager, wyłączenie synchroniczne rozwiązało problem. (deliveryMode =.FastFormat może również zapewnić dodatkowe wzmocnienie wydajności, ale kompromisem jest miniaturka o niższej jakości).

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! 
    }) 
Powiązane problemy