2015-05-29 17 views
5

nasıl kullanılır: BenZaten SO bu soru olduğunu biliyorum ama verilen cevap tam/tatmin edici olduğunu sanmıyorum PHCachingImageManager

I ulaşmak istediğiniz ne How can IOS Photos app can show hundreds of photos in one screen?

whatsapp'ta (iOS) görüntü seçimi gibi bir şey istiyorum (ekran görüntüsüne bakın). Kamerayı açtığınızda, galerinizdeki tüm görüntüleri görebileceğiniz yatay bir kaydırıcı da var.

let options = PHFetchOptions() 

options.sortDescriptors = [ 
    NSSortDescriptor(key: "creationDate", ascending: true) 
] 
if let results = PHAsset.fetchAssetsWithMediaType(.Image, options: options) { 

    results.enumerateObjectsUsingBlock { (object, idx, _) in 
     if let asset = object as? PHAsset { 
      Variables.assets.append(asset) 
     } 
    } 

    println(Variables.assets.count) 

    Variables.imageManager.startCachingImagesForAssets(Variables.assets, targetSize: CGSizeMake(viewWidth, viewWidth), contentMode: .AspectFill, options: self.requestOptions) 
} 

Daha sonra bir UITableViewController görüntüleri yükleyip üzerine aşağıdaki işlevi çağırır: Ben

Şu anda benim appDelegate aşağıdaki kodu var çalıştığım şey

whatsapp screenshot kaydırma:

Bu iyi çalışıyor ancak her uygulamada tüm varlıklarımın önbelleğe alındığı sorunu var. Bu benim problemim için doğru yaklaşım mı? Galeri fotoğraflarını whatsapp gibi gerçek zamanlı olarak nasıl görüntüleyebilirim?

+0

Öğeleri neden tekrar alabileceğinizi öğrenmek istersiniz? Bazı varlıklar, uygulamanızın öldürülmesinden sonra silinmiş/eklenmiş/değiştirilmiş olabileceğinden bunları saklamak zor olabilir. Ayrıca hepsini tekrar almak zorunda değilsiniz. Kullanıcıyı o anda ekranda göstermek için ihtiyacınız olanları getirmelisiniz. Bunları depolamanın arkasındaki ihtiyaç bağlamında yardımcı olacaktır. – jarora

+0

@jarora Bütün sorumu, kod ve elde etmek istediğim bir örnek olarak düzenledim. –

cevap

3

Bkz. Bu Photos Framework example Bu projede, AAPLAssetGridViewController.m dosyasına bakmanız ve kaydırma konumunu, kaydırma konumunuza göre nasıl işleyeceğini görmeniz gerekir.

- (void)updateCachedAssets 
     { 
      BOOL isViewVisible = [self isViewLoaded] && [[self view] window] != nil; 
      if (!isViewVisible) { return; } 

      // The preheat window is twice the height of the visible rect 
      CGRect preheatRect = self.collectionView.bounds; 
      preheatRect = CGRectInset(preheatRect, 0.0f, -0.5f * CGRectGetHeight(preheatRect)); 

      // If scrolled by a "reasonable" amount... 
      CGFloat delta = ABS(CGRectGetMidY(preheatRect) - CGRectGetMidY(self.previousPreheatRect)); 
      if (delta > CGRectGetHeight(self.collectionView.bounds)/3.0f) { 

       // Compute the assets to start caching and to stop caching. 
       NSMutableArray *addedIndexPaths = [NSMutableArray array]; 
       NSMutableArray *removedIndexPaths = [NSMutableArray array]; 

       [self computeDifferenceBetweenRect:self.previousPreheatRect andRect:preheatRect removedHandler:^(CGRect removedRect) { 
        NSArray *indexPaths = [self.collectionView aapl_indexPathsForElementsInRect:removedRect]; 
        [removedIndexPaths addObjectsFromArray:indexPaths]; 
       } addedHandler:^(CGRect addedRect) { 
        NSArray *indexPaths = [self.collectionView aapl_indexPathsForElementsInRect:addedRect]; 
        [addedIndexPaths addObjectsFromArray:indexPaths]; 
       }]; 

       NSArray *assetsToStartCaching = [self assetsAtIndexPaths:addedIndexPaths]; 
       NSArray *assetsToStopCaching = [self assetsAtIndexPaths:removedIndexPaths]; 

       [self.imageManager startCachingImagesForAssets:assetsToStartCaching 
                targetSize:AssetGridThumbnailSize 
                contentMode:PHImageContentModeAspectFill 
                 options:nil]; 
       [self.imageManager stopCachingImagesForAssets:assetsToStopCaching 
                targetSize:AssetGridThumbnailSize 
                contentMode:PHImageContentModeAspectFill 
                 options:nil]; 

       self.previousPreheatRect = preheatRect; 
      } 
     } 
     //In your case this computeDifference method changes to handle horizontal scrolling 
      - (void)computeDifferenceBetweenRect:(CGRect)oldRect andRect:(CGRect)newRect removedHandler:(void (^)(CGRect removedRect))removedHandler addedHandler:(void (^)(CGRect addedRect))addedHandler 
      { 
       if (CGRectIntersectsRect(newRect, oldRect)) { 
        CGFloat oldMaxY = CGRectGetMaxY(oldRect); 
        CGFloat oldMinY = CGRectGetMinY(oldRect); 
        CGFloat newMaxY = CGRectGetMaxY(newRect); 
        CGFloat newMinY = CGRectGetMinY(newRect); 
        if (newMaxY > oldMaxY) { 
         CGRect rectToAdd = CGRectMake(newRect.origin.x, oldMaxY, newRect.size.width, (newMaxY - oldMaxY)); 
         addedHandler(rectToAdd); 
        } 
        if (oldMinY > newMinY) { 
         CGRect rectToAdd = CGRectMake(newRect.origin.x, newMinY, newRect.size.width, (oldMinY - newMinY)); 
         addedHandler(rectToAdd); 
        } 
        if (newMaxY < oldMaxY) { 
         CGRect rectToRemove = CGRectMake(newRect.origin.x, newMaxY, newRect.size.width, (oldMaxY - newMaxY)); 
         removedHandler(rectToRemove); 
        } 
        if (oldMinY < newMinY) { 
         CGRect rectToRemove = CGRectMake(newRect.origin.x, oldMinY, newRect.size.width, (newMinY - oldMinY)); 
         removedHandler(rectToRemove); 
        } 
       } else { 
        addedHandler(newRect); 
        removedHandler(oldRect); 
       } 
      } 



- (NSArray *)assetsAtIndexPaths:(NSArray *)indexPaths 
    { 
     if (indexPaths.count == 0) { return nil; } 

     NSMutableArray *assets = [NSMutableArray arrayWithCapacity:indexPaths.count]; 
     for (NSIndexPath *indexPath in indexPaths) { 
      PHAsset *asset = self.assetsFetchResults[indexPath.item]; 
      [assets addObject:asset]; 
     } 
     return assets; 
    } 

görüntü önbelleğe yöneticisi istenen boyutta sizin varlıklar ile ısınır ve daha sonra görüntü önbelleğe yöneticisi kendisinden bu bilgileri alabilirsiniz.

Umut size yardımcı olur.

+0

Merhaba, Uygulamamda kodunuzu kullanıyorum ve "PHAsset * asset = self.assetsFetchResults [indexPath.item];" satırı şu istisnayı benim için atar: *** *** Yakalanan istisna 'NSRangeException' nedeniyle uygulamayı sonlandırma , sebep: '0x1957a880: dizin (0) sınırların ötesine (0)' 'Bu her seferinde gerçekleşmez, yani HockeyApp'dan bu istisnayı biliyorum. Buna neyin sebep olabileceği hakkında bir fikrin var mı? – Banana

+0

Ben de benzer istisnalar alıyorum ama onun arkasındaki nedeni çivi mümkün değildi. Bildiğim tek geçici çözüm, varlığı "varlıklar" dizisine eklemeden önce: indexPath.item jarora

İlgili konular