關于UITableView的HeaderView循環的問題

最近寫了一個UITableView內即有section又有row的小項目,順便在row內添加btn來從新刷新這個UITableView的數據源.
一直到寫完加載 顯示ui都沒有發現有什么問題,包括內存方面,可是在添加點擊事件后,用block回調來刷新UITableView的時候發現有bug了,滾動的時候點擊會反復的跳動 UITableViewCell 搞得點擊btn后 頁面閃動很大.
初步猜測有以下一些原因:
  • 調用的方法 -reloadRowsAtIndexPaths:withRowAnimation:出現問題,使用 reloadData方法替換
  • 返回組頭的高度- tableView:heightForHeaderInSection:方法出現問題
  • 使用的- tableView: viewForHeaderInSection:設置UITableView的HeaderView的時候錯誤
    -調用 - (CGFloat)tableView: estimatedHeightForHeaderInSection:方法預估計高度出現錯誤

關于- tableView:viewForHeaderInSection:
一般這個方法- tableView:viewForHeaderInSection:我會這么調用

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *view = [[UIView alloc] init];
    //設置數據源 xxxx.....
    return view;
}

突然感覺這個方法應該向cell那樣 有循環的

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId forIndexPath:indexPath];
 //設置數據源 xxxx.....
    return cell;
}

在實例化cell的時候一般都會實現 -dequeueReusableCellWithIdentifier:forIndexPath:方法來達到循環使用cell的目的.
所以看了相關apple的API發現確實有一個方法 來設置這個UITableViewHeader的,是在iOS6引入的一個類UITableViewHeaderFooterView你需要使用 -initWithReuseIdentifier:方法來使HeaderView達到循環的目的

從寫此方法后run發現HeaderView竟然木有了...木有了....-_-!

一定是哪里出了問題,谷歌搜索后說需要在實例化的 HeaderView內種重寫 ``` - (instancetype)initWithReuseIdentifier:reuseIdentifier


  • (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier{

    self = [super initWithReuseIdentifier:reuseIdentifier];
    if (self) {
    return [[[NSBundle mainBundle] loadNibNamed:@"headerView" owner:nil options:nil] lastObject];
    }
    return self;
    }

重寫```- (UIView *)tableView:viewForHeaderInSection:```方法

pragma mark 返回每組的頭部視圖

  • (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
    static NSString *viewIdentfier = @"headView";
    headerView *headerViews = [tableView dequeueReusableHeaderFooterViewWithIdentifier:viewIdentfier];
    if(!headerViews){
    headerViews = [[headerView alloc] initWithReuseIdentifier:viewIdentfier];
    }
    //設置數據源 xxxx.....
    //去除顏色警告..
    //UITableViewHeaderFooterView has been deprecated. Please use contentView.backgroundColor instead 將背景顏色設置成默認即可去除 在xib內
    headerViews.contentView.backgroundColor = [UIColor blueColor];
    return headerViews;
    }
在寫完后 ```run```有報警告 ``` UITableViewHeaderFooterView has been deprecated. Please use contentView.backgroundColor instead ``` 需要從新設置HeaderView的頭部顏色要實現```contentView```的方法,直接在xib內修改顏色不起作用哈,把xib的顏色設置成默認,這個警告就消失了,這個是個坑.不過,在xib內在添加一個view改變view顏色也可用達到改變背景顏色的目的.

回歸正題,可悲的事情點擊btn刷新UITableViewCell后,cell依然亂跳,
重寫 ``` - tableView:heightForHeaderInSection:``` 方法....好吧,跟這個方法沒關系,略過一些廢話.
 
就最后一個了 ```- (CGFloat)tableView:estimatedHeightForHeaderInSection:```
這個方法是iOS7出來的,問題確實出現在這里,在點擊cell內的btn調用刷新的時候 高度應該是已經算好了的,不應該在預估一個定值的高度,所以在block回調內當點擊btn后 這個方法應該返回真實的高度,而不是預估的高度.
注意:```self.estimatedHeightForRow```是我定義的屬性,在cell的block回調內設置成YES;

  • (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section{
    // 去除來回跳轉的bug-->
    //在剛剛進入這個控制器的時候 這個 預算高度被激活,當點擊cell刷新的時候這個 預算返回 指定的高度
    if (self.estimatedHeightForRow) {
    NSString * str = [self strE:list_[section]];
    CGFloat textH = [self autoCalculateWidthOrHeight:MAXFLOAT width:[UIScreen mainScreen].bounds.size.width - 20 fontsize:15 content:str] + 45;
    return textH;
    }else{
    return 100;
    }
    }

//根據str的內容計算HeaderView的高度
-(float)autoCalculateWidthOrHeight:(float)height
width:(float)width
fontsize:(float)fontsize
content:(NSString*)content
{
//計算出rect
CGRect rect = [content boundingRectWithSize:CGSizeMake(width, height)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontsize]} context:nil];

//判斷計算的是寬還是高
if (height == MAXFLOAT) {
    return rect.size.height;
}
else{
    return rect.size.width;
}

}

補充:
有得時候,你會感覺 這個根據文字算高度的方法 ```-boundingRectWithSize: options:attributes: context:```這個方法算的不準,有那么幾個原因
1. 參數 ```options: ```不是```NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading```
2. attributes:參數錯誤
3. 在xib內設置的樣式不是```System```樣式的

![xib_lable_Image.png](http://upload-images.jianshu.io/upload_images/1447422-b9876f9529ebe8a6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

具體的代碼還在整理中.......


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容