2

我對這個問題提出了我的問題Display photolibrary images in an effectual way iPhoneHighly efficient UITableView "cellForRowIndexPath" method to bind the PhotoLibrary imagesNSBlockOperation或NSOperation with ALAsset Block使用ALAsset顯示照片庫圖像URL

所以我想請求的答案不重複這一個沒有閱讀下面的細節:)

讓我們來到這個問題,

我研究一下我上面提到的問題的詳細和我找到了關於操作隊列來自here的文檔。

所以我創建了一個示例應用程序,通過ALAsset塊使用操作隊列顯示七個照片庫圖像。

以下是示例應用程序的詳細信息。

步驟1:

在NSOperationalQueueViewController viewDidLoad中方法,我已經檢索到的所有光畫廊ALAsset URLs在名爲urlArray陣列。

步驟2:

在所有的URL被添加到urlArray,所述如果(組=零!)條件將在assetGroupEnumerator假,所以我已經創建了一個NSOperationQueue,然後創建7分的UIImageView的通過for循環,創造了我的NSOperation子類對象與相應的圖像的視圖URL爲每一個和添加他們到NSOperationQueue

請參閱我的NSOperation子類here

請參閱我的實施(VierwController)類here

讓我們來談談這個問題。

它不一致地顯示所有七個圖像。一些圖像丟失。缺少的順序是多次更改(一次不顯示第六和第七次,而另一次不顯示第二次和第三次)。控制檯日誌顯示找不到照片圖片號碼。但是,URL會被正確記錄。

你可以看到日誌的詳細信息here

我的課上有錯誤嗎?

此外,當我通過上述operational queue文檔時,我已閱讀約NSBlockOperation。在處理ALAsset塊時,是否需要執行NSBlockOperation而不是NSOperation

NSBlockOperation介紹說

使用原樣執行一個或多個塊對象, 併發的類。因爲它可以執行多個塊,操作對象塊使用組語義進行操作;只有當所有關聯塊都完成執行時,纔會考慮完成操作本身 。

如何在ALAsset塊中實現NSBlockOperation關於我的示例應用程序?

我已經通過堆棧溢出問題Learning NSBlockOperation。但是,我沒有想到用ALAsset塊實現NSBlockOperation

回答

4

您的DisplayImages NSOperation子類中有一行用於更新UI(DisplayImages。M線54):

self.imageView.image = topicImage; 

此操作隊列在後臺線程上運行,而我們知道,你應該只在主線程中更新UI的狀態。由於更新的圖像視圖的視圖絕對更新UI,這可以簡單地固定通過用包裹呼叫:

dispatch_async(dispatch_get_main_queue(), ^{ 
    self.imageView.image = topicImage; 
}); 

這使異步調用在主隊列來更新與所述圖像的UIImageView的。它是異步的,因此您的其他任務可以在後臺進行調度,並且它在主隊列(主線程)上運行時很安全。

+0

太棒了......「我看到他之前在線,」你應該只更新主線程上UI的狀態「。現在我很好理解它的含義:) ..謝謝abizern。你是rockzzzz ... – 2012-07-24 07:00:44

5

這是關於「如何使用ALAsset庫訪問iPhonePhoto Library中的所有圖像並在像iPhoneSimulator之類的UIScrollView上顯示它們」的教程。 首先將AssetsLibrary.framework添加到您的項目中。

然後在您的viewController.h文件中導入#import <AssetsLibrary/AssetsLibrary.h>頭文件。

這是你viewController.h文件

#import <UIKit/UIKit.h> 
#import <AssetsLibrary/AssetsLibrary.h> 
#import "AppDelegate.h" 

@interface ViewController : UIViewController <UIScrollViewDelegate> 
{ 
    ALAssetsLibrary *assetsLibrary; 
    NSMutableArray *groups; 
    ALAssetsGroup *assetsGroup; 

    // I will show all images on `UIScrollView` 
    UIScrollView *myScrollView; 

    UIActivityIndicatorView *activityIndicator; 

    NSMutableArray *assetsArray; 
    // Will handle thumbnail of images 
    NSMutableArray *imageThumbnailArray; 
    // Will handle original images 
    NSMutableArray *imageOriginalArray; 

    UIButton *buttonImage; 
} 

-(void)displayImages; 
-(void)loadScrollView; 

@end 

這是你的viewController.m文件 - viewWillAppear:

#import "ViewController.h" 
#import <QuartzCore/QuartzCore.h> 

@implementation ViewController 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 

    assetsArray = [[NSMutableArray alloc]init]; 
    imageThumbnailArray = [[NSMutableArray alloc]init]; 
    imageOriginalArray = [[NSMutableArray alloc]init]; 

    myScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0.0, 0.0, 320.0, 416.0)]; 
    myScrollView.delegate = self; 
    myScrollView.contentSize = CGSizeMake(320.0, 416.0); 
    myScrollView.backgroundColor = [UIColor whiteColor]; 

    activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
    activityIndicator.center = myScrollView.center; 
    [myScrollView addSubview:activityIndicator]; 
    [self.view addSubview:myScrollView]; 

    [activityIndicator startAnimating]; 

} 

viewDidAppear:

-(void)viewDidAppear:(BOOL)animated 
{ 
if (!assetsLibrary) { 
     assetsLibrary = [[ALAssetsLibrary alloc] init]; 
    } 
    if (!groups) { 
    groups = [[NSMutableArray alloc] init]; 
    } 
else { 
    [groups removeAllObjects]; 
} 

ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) { 
     //NSLog(@"group %@",group); 
     if (group) { 
      [groups addObject:group]; 
     //NSLog(@"groups %@",groups); 
    } else { 
     //Call display Images method here. 
     [self displayImages]; 
     } 
}; 
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error) { 
    NSString *errorMessage = nil; 
     switch ([error code]) { 
     case ALAssetsLibraryAccessUserDeniedError: 
      case ALAssetsLibraryAccessGloballyDeniedError: 
      errorMessage = @"The user has declined access to it."; 
       break; 
      default: 
      errorMessage = @"Reason unknown."; 
      break; 
    } 
    }; 
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:listGroupBlock failureBlock:failureBlock]; 

} 

這是displayImages:方法體

-(void)displayImages 
{ 
// NSLog(@"groups %d",[groups count]); 
    for (int i = 0 ; i< [groups count]; i++) { 
    assetsGroup = [groups objectAtIndex:i]; 
     if (!assetsArray) { 
     assetsArray = [[NSMutableArray alloc] init]; 
     } 
     else { 
     [assetsArray removeAllObjects]; 
    } 

    ALAssetsGroupEnumerationResultsBlock assetsEnumerationBlock = ^(ALAsset *result, NSUInteger index, BOOL *stop) { 

      if (result) { 
       [assetsArray addObject:result]; 
      } 
    }; 
     ALAssetsFilter *onlyPhotosFilter = [ALAssetsFilter allPhotos]; 
     [assetsGroup setAssetsFilter:onlyPhotosFilter]; 
     [assetsGroup enumerateAssetsUsingBlock:assetsEnumerationBlock]; 

    } 

    //Seprate the thumbnail and original images 
    for(int i=0;i<[assetsArray count]; i++) 
    { 
     ALAsset *asset = [assetsArray objectAtIndex:i]; 
     CGImageRef thumbnailImageRef = [asset thumbnail]; 
     UIImage *thumbnail = [UIImage imageWithCGImage:thumbnailImageRef]; 
     [imageThumbnailArray addObject:thumbnail]; 

     ALAssetRepresentation *representation = [asset defaultRepresentation]; 
     CGImageRef originalImage = [representation fullResolutionImage]; 
     UIImage *original = [UIImage imageWithCGImage:originalImage]; 
     [imageOriginalArray addObject:original]; 
    } 

    [self loadScrollView]; 
} 

現在你有兩個array一個是imageThumbnailArray,另一個是imageOriginalArray。 使用imageThumbnailArrayUIScrollView上顯示,您的滾動速度不會很慢....並使用imageOriginalArray來放大圖像預覽。

'loadScrollView:' 方法,這是UIScrollView如何相似圖片iPhoneSimulator

#pragma mark - LoadImages on UIScrollView 
-(void)loadScrollView 
{ 
    float horizontal = 8.0; 
    float vertical = 8.0; 

    for(int i=0; i<[imageThumbnailArray count]; i++) 
    { 
     if((i%4) == 0 && i!=0) 
     { 
      horizontal = 8.0; 
      vertical = vertical + 70.0 + 8.0; 
     } 

     buttonImage = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [buttonImage setFrame:CGRectMake(horizontal, vertical, 70.0, 70.0)]; 
     [buttonImage setTag:i]; 
    [ buttonImage setImage:[imageThumbnailArray objectAtIndex:i] forState:UIControlStateNormal]; 
     [buttonImage addTarget:self action:@selector(buttonImagePressed:) forControlEvents:UIControlEventTouchUpInside]; 
     [myScrollView addSubview:buttonImage]; 
     horizontal = horizontal + 70.0 + 8.0; 

    } 

    [myScrollView setContentSize:CGSizeMake(320.0, vertical + 78.0)]; 
    [activityIndicator stopAnimating]; 
    [activityIndicator removeFromSuperview]; 
} 

在這裏,你可以找到像button已經被點擊了哪個 -

#pragma mark - Button Pressed method 
-(void)buttonImagePressed:(id)sender 
{ 
    NSLog(@"you have pressed : %d button",[sender tag]); 
} 

希望本教程將幫助您和許多搜索相同的用戶。謝謝!

+0

感謝您的快速回復。我需要使用他們的ALAsset網址顯示照片庫圖像。讓我們考慮在啓動應用程序之前,我已經在我的數據庫中包含了所有的照片庫圖片網址。對於上述(我的答案)的目的,我可以通過「UIImagePickerController」顯示照片庫圖像,而無需使用ALSAsset。對?所以請張貼答案「顯示照片庫圖像使用他們的ALAsset網址,我想你可以回答。 – 2012-07-23 07:26:57

+0

正在使用UIImagePickerController ????,.... nslog」assetsArray「..你會看到它包含所有圖片的網址... – TheTiger 2012-07-23 07:29:15

+0

對不起,如果我錯了:)。讓我澄清一件事情。我認爲assetsArray數組包含ALAsset對象,而不是一個NSUrl或資源的網址,對嗎? – 2012-07-23 07:33:26