最近寫了一個UITableView內(nèi)即有section又有row的小項目,順便在row內(nèi)添加btn來從新刷新這個UITableView的數(shù)據(jù)源.
一直到寫完加載 顯示ui都沒有發(fā)現(xiàn)有什么問題,包括內(nèi)存方面,可是在添加點擊事件后,用block回調(diào)來刷新UITableView的時候發(fā)現(xiàn)有bug了,滾動的時候點擊會反復(fù)的跳動 UITableViewCell 搞得點擊btn后 頁面閃動很大.
初步猜測有以下一些原因:
- 調(diào)用的方法
-reloadRowsAtIndexPaths:withRowAnimation:
出現(xiàn)問題,使用reloadData
方法替換 - 返回組頭的高度
- tableView:heightForHeaderInSection:
方法出現(xiàn)問題 - 使用的
- tableView: viewForHeaderInSection:
設(shè)置UITableView的HeaderView
的時候錯誤
-調(diào)用- (CGFloat)tableView: estimatedHeightForHeaderInSection:
方法預(yù)估計高度出現(xiàn)錯誤
關(guān)于- tableView:viewForHeaderInSection:
一般這個方法- tableView:viewForHeaderInSection:
我會這么調(diào)用
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
//設(shè)置數(shù)據(jù)源 xxxx.....
return view;
}
突然感覺這個方法應(yīng)該向cell那樣 有循環(huán)的
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId forIndexPath:indexPath];
//設(shè)置數(shù)據(jù)源 xxxx.....
return cell;
}
在實例化cell的時候一般都會實現(xiàn) -dequeueReusableCellWithIdentifier:forIndexPath:
方法來達到循環(huán)使用cell的目的.
所以看了相關(guān)apple的API發(fā)現(xiàn)確實有一個方法 來設(shè)置這個UITableViewHeader的,是在iOS6引入的一個類UITableViewHeaderFooterView
你需要使用 -initWithReuseIdentifier:
方法來使HeaderView
達到循環(huán)的目的
從寫此方法后run
發(fā)現(xiàn)HeaderView竟然木有了...木有了....-_-!
一定是哪里出了問題,谷歌搜索后說需要在實例化的 HeaderView內(nèi)種重寫 ``` - (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];
}
//設(shè)置數(shù)據(jù)源 xxxx.....
//去除顏色警告..
//UITableViewHeaderFooterView has been deprecated. Please use contentView.backgroundColor instead 將背景顏色設(shè)置成默認即可去除 在xib內(nèi)
headerViews.contentView.backgroundColor = [UIColor blueColor];
return headerViews;
}
在寫完后 ```run```有報警告 ``` UITableViewHeaderFooterView has been deprecated. Please use contentView.backgroundColor instead ``` 需要從新設(shè)置HeaderView的頭部顏色要實現(xiàn)```contentView```的方法,直接在xib內(nèi)修改顏色不起作用哈,把xib的顏色設(shè)置成默認,這個警告就消失了,這個是個坑.不過,在xib內(nèi)在添加一個view改變view顏色也可用達到改變背景顏色的目的.
回歸正題,可悲的事情點擊btn刷新UITableViewCell后,cell依然亂跳,
重寫 ``` - tableView:heightForHeaderInSection:``` 方法....好吧,跟這個方法沒關(guān)系,略過一些廢話.
就最后一個了 ```- (CGFloat)tableView:estimatedHeightForHeaderInSection:```
這個方法是iOS7出來的,問題確實出現(xiàn)在這里,在點擊cell內(nèi)的btn調(diào)用刷新的時候 高度應(yīng)該是已經(jīng)算好了的,不應(yīng)該在預(yù)估一個定值的高度,所以在block回調(diào)內(nèi)當點擊btn后 這個方法應(yīng)該返回真實的高度,而不是預(yù)估的高度.
注意:```self.estimatedHeightForRow```是我定義的屬性,在cell的block回調(diào)內(nèi)設(shè)置成YES;
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section{
// 去除來回跳轉(zhuǎn)的bug-->
//在剛剛進入這個控制器的時候 這個 預(yù)算高度被激活,當點擊cell刷新的時候這個 預(yù)算返回 指定的高度
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;
}
}
//根據(jù)str的內(nèi)容計算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;
}
}
補充:
有得時候,你會感覺 這個根據(jù)文字算高度的方法 ```-boundingRectWithSize: options:attributes: context:```這個方法算的不準,有那么幾個原因
1. 參數(shù) ```options: ```不是```NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading```
2. attributes:參數(shù)錯誤
3. 在xib內(nèi)設(shè)置的樣式不是```System```樣式的

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