2014-10-10 12 views
8

Pracuję nad aplikacją, która polega na pokazywaniu dużej liczby zdjęć na ekranie z wielu źródeł.W jaki sposób aplikacja IOS Photos może wyświetlać setki zdjęć na jednym ekranie?

Zastanawiam się, w jaki sposób jabłko może zrobić ten "kafelek zdjęć" w swojej aplikacji do zdjęć? Przy tak dużej ilości zdjęć, moim zdaniem aplikacja powinna wyświetlać ostrzeżenie o zapamiętywaniu z mniejszą ilością zdjęć (nawet jeśli ładuję zdjęcia w "rozmiarze miniaturek") jednocześnie, ale widzę, że może wyświetlać setki zdjęć na jednym ekranie podczas powiększania na zewnątrz.

Jednym ze sposobów, w jaki mogę myśleć, są te widoki, które nie są pojedynczymi zdjęciami, ale są pojedynczymi kaflami generowanymi na zdjęciach w czasie rzeczywistym, dzięki czemu aplikacja pokazuje tylko 2-3 zdjęcia naraz. Ale to wciąż wymaga dużej mocy obliczeniowej procesora i czasu, aby wygenerować tak szybko. Mogę natychmiast powiększyć lub pomniejszyć.

Chcę uzyskać podobną funkcjonalność w mojej aplikacji, wszelkie wskazówki, jak to osiągnąć, byłyby świetne.

Dzięki za odpowiedzi.

IOS 7 Photos.app

+0

, dlaczego miałaby za dużo pamięci, jeśli miniatura jest tak mała? – dadalar

+0

@DenizAdalar, ponieważ jest za dużo zdjęć. również ładowanie "ALAsset" jest zbyt wolne, aby załadować tyle zdjęć w czasie rzeczywistym (każdy z nich jest załadowany w osobnym wątku) w mojej opinii. – dreampowder

+0

Chciałem zaimplementować coś takiego kilka dni temu, w widoku Rok mój widok kolekcji nie może być płynnie przewijany. – gabbler

Odpowiedz

10

Zrobiłem rozeznanie i okazało się, że systemów iOS 8 ma wspaniały nowe ramy nazwie

ramowa pozwala Ci łatwo cache obrazów, zadzwoń miniaturek z predefiniowanych rozmiarów i pozycji obciążenia „Zdjęcia Framework”. (stara biblioteka ALAsset miała tylko jeden rozmiar "miniatury", musiała zmienić swoją własną).

na moim teście ekran pełen zdjęć 20x20 (zawartość ekranu moich telefonów 384 obrazów), aplikacja zajmuje tylko 10 MB pamięci, a prawie nie migają podczas przewijania. Płynne przewijanie można osiągnąć poprzez optymalizację ponownego ładowania komórek.

Herezje kod Użyłem do ładowania obrazów do uicollectionview o rozmiarze 20x20 pozycja:

@import Photos; 
@interface MainViewController() 

@property (strong) PHFetchResult *assetsFetchResults; 
@property (strong) PHCachingImageManager* imageManager; 

@end 

na viewDidLoad:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.imageManager = [[PHCachingImageManager alloc] init]; 

    CGFloat scale = [UIScreen mainScreen].scale; 
    CGSize cellSize = ((UICollectionViewFlowLayout *)self.collectionViewLayout).itemSize; 
    AssetGridThumbnailSize = CGSizeMake(cellSize.width * scale, cellSize.height * scale); 

    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier]; 
    self.assetsFetchResults = [PHAsset fetchAssetsWithOptions:nil]; 
    // Do any additional setup after loading the view. 
} 

metod gromadzenia i widok DataSource:

#pragma mark <UICollectionViewDataSource> 

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 
    return 1; 
} 


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 
    return self.assetsFetchResults.count; 
} 

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

    [self.imageManager requestImageForAsset:self.assetsFetchResults[indexPath.item] 
           targetSize:CGSizeMake(20, 20) 
           contentMode:PHImageContentModeAspectFill 
            options:nil resultHandler:^(UIImage *result, NSDictionary* info){ 

             UIImageView* imgView = (UIImageView*)[cell.contentView viewWithTag:999]; 
             if(!imgView) { 
              imgView = [[UIImageView alloc] initWithFrame:[cell.contentView bounds]]; 
              imgView.tag = 999; 
              [cell.contentView addSubview:imgView]; 
             } 
             imgView.image = result; 
            }]; 
    // Configure the cell 

    return cell; 
} 

To wszystko!

+0

Czy możesz podać przykładowy projekt, zmodyfikowałem kod zdjęć z jabłka, zmieniając tylko rozmiar elementu kolekcji na 20x20, I uzyskać wykorzystanie pamięci 15,6 megapiksela na moim iPhone 4S, przewijanie nie jest takie gładkie. AssetGridThumbnailSize ma rozmiar 40x40, ale skala to 2 dla 4S, więc rozmiar docelowy to także 40x40 zamiast 20x20. Jak udało ci się uzyskać tylko 10 MB pamięci przez optymalizację przeładowywania komórek? – gabbler

+1

@CarouselMin testuję także na iphone4 btw, heres projektu: https: // github.com/dreampowder/photosSample – dreampowder

+0

Przetestowałem projekt i jego wykorzystanie pamięci wynosi 10mb ~ 11mb, co jest lepsze, tylko że obraz jest trochę niewyraźny, zmieniając targetSize: CGSizeMake (20, 20) na targetSize: CGSizeMake (40, 40) robić zdjęcia jasne, ale użycie idzie do 11 ~ 12mb, przewijanie jest trochę powolne, a mimo to jest lepsze niż kod początkowy, który buforuje niektóre zdjęcia podczas przewijania. – gabbler

Powiązane problemy