textview 在TableviewCell自適應

weixin_34208283發表於2017-09-15

提問
1.自適應cell高度,你會幾種?
2.約束,區域性,適配 你會幾種?

  1. textview 是否會自定義高度。

這裡textview實現的cell IOS 8 自適應方法。 使用Masonry佈局,使用runtimer給分類,進行動態新增方法,和交換方法。
整體的邏輯,textview ,首先自適應高度,然後把高度和輸入的字元用block 的方式,傳到cell裡,viewController通過代理事件,進行更新自適應高度!
我試過很多方法,和各種回撥,還是不能達到預期的效果,就是解決不了cell跟著更新!(這個很皮啊!)
難點,在於textview,和cell的結合,textview怎麼樣才能實時的自適應來適應高度,這裡肯定想要了用KVO KVC 觀察著啊,但是這些我都無法很巧妙和結合起來使用,也沒有達到預期的效果bug一大推! 然後去github上找了找,發現盡然用到runtimer! 於是就下了狠心一定要把這個東西給弄懂!
下面我一步一步的解讀下來

首先我們看,viewconeroller做了些啥。。!
self.dataSource = [NSMutableArray array];
for (NSInteger i = 0; i < 6; i++) {
[self.dataSource addObject:@""];
}
if (!_titls) {
_titls = [NSMutableArray array];
for (int i = 1; i<100; i++) {
[_titls addObject:[NSString stringWithFormat:@"%d.",i]];
}
}
return _titls;
//建立了一個cell,設定了一個代理。給控制元件賦值了!
LSTextViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.delegate = self;
cell.textView.text = self.dataSource[indexPath.row];
cell.label.text = self.titls[indexPath.row];

//通過cell 的出indexpath,獲得cell的繫結indexpath
-(void)textViewCell:(LSTextViewCell *)cell textChange:(NSString )text{
NSIndexPath
indexPath = [self.tableView indexPathForCell:cell];
[self.DatasoucerDit setValue:text forKey:[NSString stringWithFormat:@"%ld",indexPath.row]];

if (!indexPath) {
return;
}

//將物件anObject插入陣列的index元素
[self.dataSource replaceObjectAtIndex:indexPath.row withObject:text];
}
//更新
-(void)textViewCell:(LSTextViewCell)cell textHeightChange:(NSString)text{
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
//在上面,就例項化出來了cell,賦值,遵從了一個delegate;代理分別是一個更新和取值的方法。

//在來看cell這個控制元件做了啥
控制元件的新增我就不說了!
-(void)textViewDidChange:(UITextView *)textView{
if (self.textView.text.length > self.maxNumberWords && self.maxNumberWords > 0) {
self.textView.text = [self.textView.text substringToIndex:self.maxNumberWords-1];
}
//判斷delegate 是否為空,判斷是否響應了 dalegate方法
if (self.delegate && [self.delegate respondsToSelector:@selector(textViewCell:textChange:)]) {
//代理傳值,這個是text改變!
//這個是更新tableview
[self.delegate textViewCell:self textChange:self.textView.text];

}
}
這個方法就是限制text的,給viewcontroller的text ,做了一個限制字元的輸入!
[self.textView setHeightDidChangeBlock:^(NSString *text, CGFloat height) {

[weakSelf.textView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_greaterThanOrEqualTo(@(height)).priority(888);

}];
//高度改變,這個就把text 傳出去了。。
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(textViewCell:textHeightChange:)]) {
[weakSelf.delegate textViewCell:weakSelf textHeightChange:text];

}

[weakSelf layoutIfNeeded];
}];
//這裡也只是改變約束,設定自適應
[self.textView setTextDidSetBlock:^(NSString *text, CGFloat textHeight) {
[weakSelf.textView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_greaterThanOrEqualTo(@(textHeight)).priority(888);

}];

[weakSelf layoutIfNeeded];
}];

上面就算完了,邏輯都沒在裡面寫的,重頭戲來了。。
自定義的textview,主要做了寫什麼呢?
首先設定本身的屬性讓他不能夠滾動自適應起來來。
監聽Text屬性值的變化
sizeThatFits 這個方法返回實際的尺寸,ceil 在向上取整
在判斷是否 高度變化,給他傳出去給cell去修改約束
可以說到這裡就已經結束了一切的程式碼了。你的cell 和textview都已經可以自適應了。
但是他還是不完美的,他不能設定佔位符,沒有提示符。
這樣的話,就只有使用runtime來設定了。。
其實說白了,就給他動態新增屬性就行了,不過這個你不能亂新增你要看下需要的屬性是不是能夠跟你拿來做臨時的UI 能夠很好的結合,這樣的話,你寫起來就方便!
提示符,提示符的顏色,和花字型,全部都用一個lable來代替! 因為labe全部都有相同的屬性!這樣就很方便了。。我直接set方法在我內部修改就OK了。
然後你得把lable的frame算出來,還有是否顯示。(這裡方法有很多種)
作者用的確實,比較難的! 使用觀察者 不知道為什麼作者那麼喜歡觀察者模式!(個人認為觀察者是比較麻煩的,還有很容易出問題),作者這裡就會出問題,因為你要考慮到他的銷燬!
這裡作者有來搞runtime!
他把方法dealloc方法互動,去銷燬觀察者!和通知!

相關文章