iOS開發之有間距的UITableViewCell

YungFan發表於2017-12-13

UITableView是最常用的一個iOS控制元件,現要做一個如下圖的UITableView,其中白色部分就是cell,可是預設的UITableView中cell之間是沒有間隔的,那麼辦呢?網上有2種做法,我這裡順帶提一下吧

效果圖.png

1、方式一
通過設定cell的contentView來間接實現,在cell的contentView的頂部或者底部留下一定的間距,這樣就會有cell間就有間距的效果。但是這種方式在cell有點選效果的時候,會很明顯的看出有分層,因為這時候cell是被點選的,contentView都會有系統點選的陰影效果。這種方式在cell左滑刪除,置頂等操作的時候,左滑出的檢視會高出一部分(左滑顯示出的高度=(cell的高度-留下的間距高度)+ 留下的間距高度),很顯然這種方式有致命缺陷。

2、方式二
通過分組的方式間接的實現,每組的Header可以當做是cell之間的間距,每組中只有一個cell,程式碼如下:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ return 10;}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
 { return 10;}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 { return 1;}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
 { return 100;}

複製程式碼

但是呢,這還是會出現一個問題,因為系統預設分組的時候每組的Header會停留在tableview的頂部,這要怎麼處理呢?網上也有一種解決辦法

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {    
if (scrollView == self.tableView)    {        
    CGFloat sectionHeaderHeight = 10;    
    if (scrollView.contentOffset.y <= sectionHeaderHeight && scrollView.contentOffset.y >= 0) {            
        scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);        
    } else if (scrollView.contentOffset.y >= sectionHeaderHeight) {
        scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);        
       }   
   }
}

複製程式碼

但是這種方式是通過scroll偏移量來監聽和改變tableview的contentInset。

補充:上面的程式碼只能設定headerView,如果想footerView也沒有粘性,怎麼辦?看到國外一位大神寫的如下程式碼

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView == self.tableView)
        {
        UITableView *tableview = (UITableView *)scrollView;
        CGFloat sectionHeaderHeight = 64;
        CGFloat sectionFooterHeight = 120;
        CGFloat offsetY = tableview.contentOffset.y;
        if (offsetY >= 0 && offsetY <= sectionHeaderHeight)
        {
            tableview.contentInset = UIEdgeInsetsMake(-offsetY, 0, -sectionFooterHeight, 0);
        }else if (offsetY >= sectionHeaderHeight && offsetY <= tableview.contentSize.height - tableview.frame.size.height - sectionFooterHeight)
        {
            tableview.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, -sectionFooterHeight, 0);
        }else if (offsetY >= tableview.contentSize.height - tableview.frame.size.height - sectionFooterHeight && offsetY <= tableview.contentSize.height - tableview.frame.size.height)         {
            tableview.contentInset = UIEdgeInsetsMake(-offsetY, 0, -(tableview.contentSize.height - tableview.frame.size.height - sectionFooterHeight), 0);
        }
    }
}
複製程式碼

優雅的方式 其實優雅的也是最簡單的方法是直接讓UITableView中的cell收縮一點,這樣UITableView的底色就是分割線的顏色了,如上圖就是橘色。這種方式只需要重寫cell的setFrame方法即可

-(void)setFrame:(CGRect)frame
{
    frame.origin.x = 10;//這裡間距為10,可以根據自己的情況調整
    frame.size.width -= 2 * frame.origin.x;
    frame.size.height -= 2 * frame.origin.x;
    [super setFrame:frame];   
}
複製程式碼

如果此時想要實現圓角也很簡單,直接加上

self.layer.masksToBounds = YES;
self.layer.cornerRadius = 8.0;
複製程式碼

此時效果圖:

圓角矩形cell.png

PS:這種方式不適合有編輯的情況,因為在編輯的時候會不停呼叫setFrame方法,導致錯亂,此時建議使用上面的第二種方案。感謝簡友的提醒,之前做的是無編輯的情況,有編輯的沒有測試。

相關文章