實作類別似Android Grid效果的列表視圖

來源:互聯網
上載者:User

 

ios裡的UITableView,功能是很強大的。但是沒有Android類似Grid的效果。比如類似解決ListView滾動卡的問題。因為UITableView的每行只支援顯示一個視圖。如果細粒度的比如類似gallery的效果,就需要自己解決了。

最近寫的一個類似效果的原型:

主要解決了:

  • 如何產生grid的樣式
  • 圖片的陰影製作效果

實現grid效果有兩個辦法:

  1. 自己編程實現,這次我就是自己實現的
  2. 使用第三方庫實現,這次沒有用,主要是時間太緊,怕陷進去再有品質問題,影響工期,等有時間了再好好看看。

這裡提到的第三方庫是AQGridView。項目首頁在這裡:https://github.com/AlanQuatermain/AQGridView

使用它產生視圖的效果:

看起來還是不錯的。見這裡:http://quatermain.tumblr.com/post/528737778/aqgridview-lives-for-my-ipad-dev-camp-hackathon,是作者的部落格。

 

首先說一下實現grid的做法。

建立一個UIView:

 

@interface CdGridView : UIView <UITableViewDelegate,UITableViewDataSource>{ 
    UITableView *_tableView; 
    NSArray *_cdInfos; 
    int _columnSize; 
}

封裝了table view,以及一個數組(資料模型),另外,每行顯示的列數。

重載了該UIView的init方法:

- (id)initWithFrame:(CGRect)frame columnSize:(int)columnSize cdInfos:(NSArray *)cdInfos{ 
    
    self = [super initWithFrame:frame]; 
    if (self) { 
        _tableView=[[UITableView alloc] initWithFrame:frame]; 
        _tableView.dataSource=self; 
        _tableView.delegate=self; 
        [_tableView setSeparatorStyle:UITableViewCellEditingStyleNone];//設定取消列表的分割線 
        _tableView.allowsSelection=NO;//設定不允許挑選清單條目 
        [self addSubview:_tableView]; 
        
        _columnSize=columnSize;//設定列數 
        _cdInfos=cdInfos; 
    } 
    return self; 
}

 

這裡通過table view屬性取消了列表分割線,以及禁用了挑選清單條目。

另外幾個方法:

 

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *simpleTableIdentifier=@"SimpleTableIdentifier"; 
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; 
    
    if(cell==nil){ 
        cell=[[[CdGridCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                reuseIdentifier:simpleTableIdentifier 
                                        columnSize:_columnSize] 
              autorelease]; 
    } 
    
    for (int i=0; i<_columnSize; i++) { 
        UIView *rowView=[cell.contentView.subviews objectAtIndex:0]; 
        UIView *imageContainerView=[rowView.subviews objectAtIndex:i]; 
        UIImageView *imageView=[imageContainerView.subviews objectAtIndex:0]; 
        
        if ([indexPath row]*_columnSize+i<[_cdInfos count]) { 
            CdInfo *cdInfo=[_cdInfos objectAtIndex:[indexPath row]*_columnSize+i]; 
            imageView.image=[UIImage imageNamed:cdInfo.coverPhotoPath]; 
            imageView.layer.shadowOpacity = 1.0; 
        }else { 
            imageView.image=nil; 
            imageView.layer.shadowOpacity = 0; 
        }        
    } 
    
    if ([[tableView indexPathsForVisibleRows] count]>0) {//剛建立的時候table view是空的 
        int _firstIndex=[[[tableView indexPathsForVisibleRows] objectAtIndex:0] row]*_columnSize; 
        NSNumber *currentFirstRecordIndex=[NSNumber numberWithInt:_firstIndex]; 
        NSDictionary *params=[[NSDictionary alloc] initWithObjectsAndKeys:currentFirstRecordIndex,@"currentFirstRecord",nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"current.first.record" object:self userInfo:params]; 
        //目前不是很准,當移動到第一行的時候,first index還是第二行的首記錄 
    } 
    
    return cell; 
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 
    NSInteger numberOfRows=ceil([_cdInfos count]*1.0/_columnSize); 
    return numberOfRows; 
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    return WIDTH/_columnSize; 
}

-(void)setFistVisibleRecord:(int)recordIndex{ 
    [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:recordIndex/_columnSize inSection:0] 
                      atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
}

 

 

用來實現table view要求的delegate,以及輔助方法。最後一個setFistVisibleRecord:方法,是用於設定列表顯示的首記錄。有時候我們需要顯示比如從第17個記錄開始,這個方法可以協助將第17個記錄所在行顯示在頁面的第一行上。

往下,說一下陰影製作效果的實現,其實就是在原有的UIImageView下面再顯示一個半透明陰影的矩形框,矩形框的邊緣是圓弧的,這樣看起來比較自然。

可通過類似下面的代碼來實現:

imageView.layer.shadowColor=[UIColor darkGrayColor].CGColor; 
imageView.layer.shadowOffset = CGSizeMake(MARGIN-2, MARGIN-2); 
imageView.layer.shadowOpacity = 0.8; 
imageView.layer.shadowRadius = 3.0; 
imageView.layer.shadowPath = [UIBezierPath bezierPathWithRect:imageView.bounds].CGPath; 

 

這裡用到了貝茲路徑來設定陰影的path,否則效能比較差。

看下這個,就知道陰影的效果了:

 

這是屏蔽了設定UIImage後的樣子,即沒有設定圖片,只有陰影的樣子。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.