簡(jiǎn)介
開(kāi)發(fā)中會(huì)大量的使用 UITableView,當(dāng)我們有很多的cell,每一行都有一個(gè) UITextView 用來(lái)進(jìn)行稍微重一些的文本編輯庇楞,這個(gè)時(shí)候榜配,你的產(chǎn)品經(jīng)理突然給你說(shuō),我希望這個(gè) UITextView會(huì)隨著書(shū)寫(xiě)內(nèi)容的長(zhǎng)度而自動(dòng)的增高姐刁。(???(??? ;)哈?
為什么要寫(xiě)這個(gè)
因?yàn)槲易约阂舱伊撕镁媒媾疲瑓⒄者^(guò)別人寫(xiě)的一些,但是到我這里都不是特別的實(shí)用聂使,尤其是進(jìn)行數(shù)據(jù)刷新的時(shí)候壁拉,如果你的行高需要改變,你去 reloadData
這個(gè)時(shí)候柏靶,鍵盤(pán)會(huì)失去響應(yīng)弃理。就算你這個(gè)時(shí)候再次將鍵盤(pán)設(shè)置為 firstResponser,這個(gè)時(shí)候你的鍵盤(pán)還是會(huì)閃一下,不是很自然屎蜓。所以寫(xiě)了一些小的 demo 痘昌,下面的具體代碼也是針對(duì)這個(gè) demo 的,點(diǎn)擊這里下載
思路
- 首先對(duì) TextView 的輸入進(jìn)行監(jiān)聽(tīng),判斷輸入的字?jǐn)?shù)的多少
- 根據(jù) UITextView 的字?jǐn)?shù)的多少去動(dòng)態(tài)的修改 UITextView 的 frame
- 監(jiān)聽(tīng) UITextView 的高度變化辆苔,如果 UITextView 比你的 cell 還要高的時(shí)候算灸,你需要?jiǎng)討B(tài)的去更新你的 UITableViewCell 的高度
實(shí)現(xiàn)
1.對(duì) UITextView 的輸入進(jìn)行監(jiān)聽(tīng),判斷輸入的字?jǐn)?shù)的多少
前人已經(jīng)有了現(xiàn)成的輪子驻啤,所以不需要你重復(fù)的造輪子菲驴。這里找到一個(gè)很好的自動(dòng)換行的 TextView我們需要使用這個(gè)來(lái)完成我們接下來(lái)的工作
[textView wzb_autoHeightWithMaxHeight:300 textViewHeightDidChanged:^(CGFloat currentTextViewHeight) {
//在此處我們已經(jīng)對(duì) UITextView 完成了監(jiān)聽(tīng),接下來(lái)我們就可以修改 UITextView 的 frame 了
}];
2.根據(jù) UITextView 的字?jǐn)?shù)的多少去動(dòng)態(tài)的修改 UITextView 的 frame
__weak typeof (self)WeakSelf = self;
__weak typeof (textView)WeakTextView = textView;
[textView wzb_autoHeightWithMaxHeight:300 textViewHeightDidChanged:^(CGFloat currentTextViewHeight) {
CGRect frame = WeakTextView.frame;
frame.size.height = currentTextViewHeight;
[UIView animateWithDuration:0.2 animations:^{
WeakTextView.frame = frame;
} completion:^(BOOL finished) {
}];
}];
3.動(dòng)態(tài)的修改cell 的高度
我們需要對(duì)單元格的高度進(jìn)行保存骑冗,然后在刷新行高的時(shí)候把高度取出來(lái)賦值赊瞬。所以我們還需要一個(gè)保存高度的字典dicHeight
__weak typeof (self)WeakSelf = self;
__weak typeof (textView)WeakTextView = textView;
// 最大高度為300 改變高度的 block
[textView wzb_autoHeightWithMaxHeight:300 textViewHeightDidChanged:^(CGFloat currentTextViewHeight) {
CGRect frame = WeakTextView.frame;
frame.size.height = currentTextViewHeight;
[UIView animateWithDuration:0.2 animations:^{
WeakTextView.frame = frame;
} completion:^(BOOL finished) {
}];
NSString *key = [NSString stringWithFormat:@"%@",indexPath];
NSNumber *height = [NSNumber numberWithFloat:currentTextViewHeight];
if (WeakSelf.dicHeight[key]) {
NSNumber *oldHeight = self.dicHeight[key];
if (oldHeight.floatValue != height.floatValue) {
[WeakSelf.dicHeight setObject:height forKey:key];
}
}
else{
[WeakSelf.dicHeight setObject:height forKey:key];
}
[WeakSelf.tableview beginUpdates];
[WeakSelf.tableview endUpdates];
}];
我們使用beginUpdates
和 endUpdates
。不使用 reloadData
贼涩。具體的原因看我之前寫(xiě)的為什么不用 ReloadData巧涧。
接下來(lái)就可以修改行高了
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *key = [NSString stringWithFormat:@"%@",indexPath];
if(self.dicHeight[key]){
NSNumber *number = self.dicHeight[key];
if (number.floatValue > 44) {
return number.floatValue;
}
}
return 44;
}
小彩蛋
通過(guò)這個(gè)你就可以簡(jiǎn)單的知道為什么不能用 reloadData
了。使用的時(shí)候把自動(dòng)行高的哪里注釋掉遥倦。簡(jiǎn)單的輸入一些東西做一些嘗試吧谤绳。
//模擬數(shù)據(jù)刷新
-(void)textViewDidChange:(UITextView *)textView{
//1.reloadData
//[self.tableview reloadData];
//2.reloadindexpath
// NSIndexPath *index = [NSIndexPath indexPathForRow:0 inSection:0];
// [self.tableview reloadRowsAtIndexPaths:@[index] withRowAnimation:UITableViewRowAnimationTop];
//3.beginupdate & endupdate
// [self.tableview beginUpdates];
// [self.tableview endUpdates];
}
總結(jié)
UITableView 作為 iOS 開(kāi)發(fā)中用到的比較多的控件,在具體的使用中總會(huì)出現(xiàn)各種各樣的問(wèn)題谊迄,自動(dòng)行高這里總算是脫坑了闷供。先寫(xiě)到這里