MyImagePicker展示了如何調用系統Photo和Album,並在自訂的UI中進行瀏覽,而這個也是很福士化的需求。
先看看這個例子的使用流程:
對於這個Sample,我主要關注兩個關鍵點:
- 調用系統Photo和Album
- UI組件的嵌套和組合
調用系統Photo和Album
IOS提供了類ALAssetsLibrary來取得Photo下面的資源(photo, album, video等),它的主要調用方式是遍曆和block回調:
NSUInteger groupTypes = ALAssetsGroupAlbum | ALAssetsGroupEvent | ALAssetsGroupFaces;[assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:listGroupBlock failureBlock:failureBlock];
以上代碼就是要遍曆ALAssetsGroupAlbum | ALAssetsGroupEvent | ALAssetsGroupFaces這三種資源,並在遍曆過程中回調listGroupBlock和failureBlock這兩個block,下面看看這兩個block的實現:
ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) { if (group) { [groups addObject:group]; } else { [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; }};ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error) { AssetsDataIsInaccessibleViewController *assetsDataInaccessibleViewController = [[AssetsDataIsInaccessibleViewController alloc] initWithNibName:@"AssetsDataIsInaccessibleViewController" bundle:nil]; NSString *errorMessage = nil; switch ([error code]) { case ALAssetsLibraryAccessUserDeniedError: case ALAssetsLibraryAccessGloballyDeniedError: errorMessage = @"The user has declined access to it."; break; default: errorMessage = @"Reason unknown."; break; } assetsDataInaccessibleViewController.explanation = errorMessage; [self presentModalViewController:assetsDataInaccessibleViewController animated:NO]; [assetsDataInaccessibleViewController release];};
邏輯很簡單,就是在遍曆過程中把資源放入groups數組並重新整理tableview。
UI組件的嵌套和組合
本例子的UI由各種UI組件嵌套組合而成,而這也體現了IOS標準化和定製化有效結合。首先看看中間的page,此page是展示某個album下所有photos,每一行展示4個photo縮微圖,點擊某個縮微圖能調轉到下個page,本例子採用的是tableview嵌套自訂的tableViewCell,並在此cell裡嵌套四個自訂的ImageView。代碼如下所示:
// Customize the appearance of table view cells.- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; AlbumContentsTableViewCell *cell = (AlbumContentsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { [[NSBundle mainBundle] loadNibNamed:@"AlbumContentsTableViewCell" owner:self options:nil]; cell = tmpCell; tmpCell = nil; } cell.rowNumber = indexPath.row; cell.selectionDelegate = self; // Configure the cell... NSUInteger firstPhotoInCell = indexPath.row * 4; NSUInteger lastPhotoInCell = firstPhotoInCell + 4; if (assets.count <= firstPhotoInCell) { NSLog(@"We are out of range, asking to start with photo %d but we only have %d", firstPhotoInCell, assets.count); return nil; } NSUInteger currentPhotoIndex = 0; NSUInteger lastPhotoIndex = MIN(lastPhotoInCell, assets.count); for ( ; firstPhotoInCell + currentPhotoIndex < lastPhotoIndex ; currentPhotoIndex++) { ALAsset *asset = [assets objectAtIndex:firstPhotoInCell + currentPhotoIndex]; CGImageRef thumbnailImageRef = [asset thumbnail]; UIImage *thumbnail = [UIImage imageWithCGImage:thumbnailImageRef]; switch (currentPhotoIndex) { case 0: [cell photo1].image = thumbnail; break; case 1: [cell photo2].image = thumbnail; break; case 2: [cell photo3].image = thumbnail; break; case 3: [cell photo4].image = thumbnail; break; default: break; } } return cell;}
在最右邊的那個page中,展示某個photo,最外層是個UIScollView,此view再嵌套一個自訂的imageView,在自訂的imageview中實現多點觸控等功能。代碼如下所示:
- (void)viewDidLoad { self.title = @"Photo"; UIScrollView *imageScrollView = (UIScrollView *)self.view; [imageScrollView setBackgroundColor:[UIColor blackColor]]; [imageScrollView setDelegate:self]; [imageScrollView setBouncesZoom:YES]; ALAssetRepresentation *assetRepresentation = [asset defaultRepresentation]; UIImage *fullScreenImage = [UIImage imageWithCGImage:[assetRepresentation fullScreenImage] scale:[assetRepresentation scale] orientation:(UIImageOrientation)[assetRepresentation orientation]]; // add touch-sensitive image view to the scroll view TapDetectingImageView *imageView = [[TapDetectingImageView alloc] initWithImage:fullScreenImage]; [imageView setDelegate:self]; [imageView setTag:ZOOM_VIEW_TAG]; [imageScrollView setContentSize:[imageView frame].size]; [imageScrollView addSubview:imageView]; [imageView release]; // calculate minimum scale to perfectly fit image width, and begin at that scale float minimumScale = [imageScrollView frame].size.width / [imageView frame].size.width; [imageScrollView setMinimumZoomScale:minimumScale]; [imageScrollView zoomToRect:CGRectMake(0.0, 0.0, imageView.frame.size.width, imageView.frame.size.height) animated:NO]; }
所以從這個例子中能學習到如何靈活地嵌套和組合多種UI組件,並把事件偵聽delegate出來。