IOS相冊功能

       做過好幾個app中都要實現圖片的相冊瀏覽的功能,有開源的庫可以用,但是我都覺得比較重,自己寫另一個比較輕的。其實相冊的功能思路是很清楚的,實現滑動中的內存重用和內存的cache。好現在我逐步講解,如何來構建簡單的相冊。

 1.首先我們來創建一個UIScrollView。

    _scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0,0, 320, 480)];
    _scrollView.delegate=self;
    _scrollView.scrollEnabled=YES;
    _scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
    _scrollView.pagingEnabled=YES;
    _scrollView.showsVerticalScrollIndicator=NO;
    _scrollView.showsHorizontalScrollIndicator=NO;
    _scrollView.backgroundColor = self.view.backgroundColor;
    [_scrollView setContentSize:CGSizeMake(320*[_itemSet count], 316)];

(大家注意到有一個_itemSet,這是一個包含了圖片數據的集合,可以是網絡上的圖片的地址,也可以是包含了封裝圖片地址的對象的實例,總值不能是UIImage的實例,不然就是失去了封裝的意義了。)

  [self.view addSubview:_scrollView];
  [self configScrowViewWithIndex:self.itemIndex withForward:NO withOrigin:YES];
   pageIndex = itemIndex;

將scrollview添加爲當前試圖的子試圖之後,我們馬上 調用

  [selfconfigScrowViewWithIndex:self.itemIndexwithForward:NOwithOrigin:YES];

     這是實現整個業務邏輯的關鍵方法,就是說去配置當前的索引應該執行的操作,第一個參數是當前的索引,比如說0就代表我是從_itemSet的第一個元素映射的圖片開始顯示;第二個參數是判斷當前是向前還是向後翻動相冊;第三個參數是表示當前是不是第一次顯示相冊。

    將itemSet的索引賦給頁數,這兩個成員一直是相等的,這樣只是爲了區別的看待這兩個序數。


2.實現我們的關鍵方法:
- (void)configScrowViewWithIndex:(int)index withForward:(BOOL)isForward withOrigin:(BOOL)isOrigin

- (void)configScrowViewWithIndex:(int)index withForward:(BOOL)isForward withOrigin:(BOOL)isOrigin
{
    if ([_itemSet count]<1) {
        return; 
    }
    //當偏移量是0的話加載當前的索引的視圖和前後的視圖(如果存在的話)
    if (isOrigin) {
        WPCellImageView *currentView = [self configItemWithIndex:index];
        if (currentView) {
            currentView.tag = CURRENTVIEWTAG;
            [_scrollView addSubview:currentView];
            
        }
        
        WPCellImageView *nextView = [self configItemWithIndex:index+1];
        if (nextView) {
            nextView.tag = NEXTVIEWTAG;
            [_scrollView addSubview:nextView];
            
        }
        WPCellImageView *lastView = [self configItemWithIndex:index-1];
        if(lastView)
        {
            lastView.tag = LASTVIEWTAG;
            [_scrollView addSubview:lastView];
        }
        
    }
    else {
        //如果向前滑動的話,加載下一張試圖的後一張試圖,同時移除上一張試圖的前一張試圖
        if (isForward) {
            if ([_scrollView viewWithTag:LASTVIEWTAG])
            {

                WPCellImageView *view = (WPCellImageView*)[_scrollView viewWithTag:
                                                                   LASTVIEWTAG];
                [view cancelImageLoad];
                [[_scrollView viewWithTag:LASTVIEWTAG]removeFromSuperview];//移出前一個視圖
            }
            if ([_scrollView viewWithTag:NEXTVIEWTAG]) 
            {                  
                //如果下個視圖存在
                UIView *currentView = [_scrollView viewWithTag:CURRENTVIEWTAG];
                currentView.tag = LASTVIEWTAG;
                UIView *view =  [_scrollView viewWithTag:NEXTVIEWTAG];
                view.tag     = CURRENTVIEWTAG;
                WPCellImageView *nextView = [self configItemWithIndex:index+1];
                if (nextView) {
                    nextView.tag = NEXTVIEWTAG;
                    [_scrollView addSubview:nextView];
                }
                
            }
        }
        //如果向後滑動的話,加載上一張試圖的前一張試圖,同時移除下一張試圖的後一張試圖
        else {
            if ([_scrollView viewWithTag:NEXTVIEWTAG]) {
                [[_scrollView viewWithTag:NEXTVIEWTAG]removeFromSuperview];//移出後一個視圖
                WPCellImageView *view = (WPCellImageView*)[_scrollView viewWithTag:
                                                                   NEXTVIEWTAG];
                [view cancelImageLoad];
            }
            if ([_scrollView viewWithTag:LASTVIEWTAG]) { //如果上個視圖存在
                UIView *currentView = [_scrollView viewWithTag:CURRENTVIEWTAG];
                currentView.tag = NEXTVIEWTAG;
                UIView *view =  [_scrollView viewWithTag:LASTVIEWTAG];
                view.tag     = CURRENTVIEWTAG;
                WPCellImageView *lastView = [self configItemWithIndex:index-1];
                if (lastView) {
                    lastView.tag = LASTVIEWTAG;
                    [_scrollView addSubview:lastView];
                }
            }
            
        }
        
    }
    
}



這裏面還調用了一個方法:

- (WPCellImageView*)configItemWithIndex:(int)index

這個方法是index所代表的索引的試圖,WPCellImageVIew是我定製的一個試圖,能夠根據圖片URL下載圖片,有一些開源庫可以用,這裏就不細說了。下面貼上這個方法的實現。

  if (index<0 || index>[_itemSet count]-1) {
        DLog(@"%d",[_itemSet count]);
        return nil;
    }
    WPWaterflowItem *dic      = [_itemSet objectAtIndex:index];
    
    WPCellImageView *firstView = [[WPCellImageView alloc]initWithFrame:CGRectMake(_scrollView.frame.size.width*index, 0, _scrollView.frame.size.width, _scrollView.frame.size.height) ];
    [firstView setURL:dic.picURL];
    return [firstView autorelease];

3.通過UIScrollview的代理方法實現圖片的顯示和內存管理


#pragma mark UIScrollView Delegate 
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat pageWidth = scrollView.frame.size.width;
    int beforeIndex = pageIndex;
    pageIndex = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    if (pageIndex>beforeIndex) {
        itemIndex ++;
        [self configScrowViewWithIndex:itemIndex withForward:YES withOrigin:NO];
    }
    else if(pageIndex<beforeIndex) {
        itemIndex --;
        [self configScrowViewWithIndex:itemIndex withForward:NO withOrigin:NO];
        
    }
    
}

呵呵,很簡單吧,滑動超過半頁的時候就去加載圖片和管理內存。


總結:總體的思路就是在一個scroolview一直保存 3張圖片,保證比較好的內存管理和流暢。


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