從Samples中入門IOS開發(六)------ Photo和Album瀏覽

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出來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章