iOS即時通訊輸入框隨字?jǐn)?shù)自適應(yīng)高度

本人最近在研究socket與聊天界面的UI,在寫聊天界面UI的時候是模仿微信的界面其中的文字輸入框會隨著字?jǐn)?shù)的多少而自適應(yīng)高度,當(dāng)然超過某個行數(shù)輸入框的高度就不會增加了變?yōu)榭蓾L動,具體效果如下。


我的思路是用約束來實現(xiàn),輸入?yún)^(qū)域用UITextView來實現(xiàn);約束可以使用AutoLayout或者是第三方庫Masonry來實現(xiàn),但是他們的實現(xiàn)原理是一樣的。為了方便我使用了Xib加AutoLayout來實現(xiàn)的,我是根據(jù)UITextView的字?jǐn)?shù),寬度固定來計算出文字的高度,從而實現(xiàn)UITextView的高度自適應(yīng)。

我們都知道一般的聊天軟件的界面(微信為例)輸入框左邊是一個按鈕切換語音或者文字,輸入框右邊是表情符號和切換出發(fā)送照片等功能;當(dāng)然本文主要是介紹輸入框TextView的自適應(yīng),原諒我把其他東西省略了。首先textView需要一個BackVew,我們拖進(jìn)去一個UIview,讓它相對于父視圖居左居右為0,居底部也為0,另外還需要給它一個初始高度,一般情況下是textView是一行文字的高度+textView距離它的頂部距離和底部距離。比如,我讓textView距離它的backView底部與頂部分別是5,textView的字號是系統(tǒng)17號字,那么textView是一行的時候它的高度就是37,而這時候backView的初始高度就是37+5+5=47。textView居底部與頂部分別是5,距離左右的具體可以根據(jù)你們設(shè)計給的UI而定。這里的關(guān)鍵是當(dāng)textView的字?jǐn)?shù)變化時,我們通過計算得到當(dāng)前字?jǐn)?shù)應(yīng)該顯示的高度,我們得到這個值后適當(dāng)?shù)恼{(diào)增backView的高度,因為backView是相對于底部約束,增加高度后就會向上增加,而textView是依據(jù)backView的頂部與底部來約束的所以就會跟隨者backView的高度變化而變化。從而實現(xiàn)textView自適應(yīng)高度。

完后上面的約束之后,我們需要把backView、textView、backView的高度約束以及backView距離底部的約束都拉到代碼中成為屬性。


在viewdidload方法里面實現(xiàn)textView的一些設(shè)置

self.textView.delegate = self;

self.textView.scrollEnabled = NO;

self.textView.scrollsToTop = NO;

self.textView.layer.borderWidth = 1;

self.textView.layer.cornerRadius = 5;

self.textView.font = [UIFont systemFontOfSize:17];

//當(dāng)textview的字符串為0時發(fā)送(rerurn)鍵無效

self.textView.enablesReturnKeyAutomatically = YES;

self.textView.keyboardType = UIKeyboardTypeDefault;

//鍵盤return樣式變成發(fā)送

self.textView.returnKeyType = UIReturnKeySend;

當(dāng)鍵盤升起的時候我們需要調(diào)整backView具體底部的距離,防止鍵盤升起遮擋textView,所以要實現(xiàn)監(jiān)聽鍵盤高度

//監(jiān)聽鍵盤

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(keyboardWasShown:)

name:UIKeyboardWillChangeFrameNotification object:nil];

實現(xiàn)當(dāng)鍵盤升起或者落下的方法

- (void)keyboardWasShown:(NSNotification*)aNotification {

// 獲取鍵盤彈出時長

CGFloat duration = [aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];

//鍵盤高度

CGRect keyBoardFrame = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

CGFloat screenH = [UIScreen mainScreen].bounds.size.height;

//調(diào)增backView距離父視圖底部的距離

_backViewBottomHCons.constant = keyBoardFrame.origin.y != screenH?keyBoardFrame.size.height:0;

[UIView animateWithDuration:duration animations:^{

[self.view layoutIfNeeded];

}];

}

設(shè)置textView的最大高度,這個與你設(shè)置的最大行數(shù)有關(guān)

// 計算最大高度 = (每行高度 * 總行數(shù) + 文字上下間距)

_maxTextH = ceil(self.textView.font.lineHeight * 4 + self.textView.textContainerInset.top + self.textView.textContainerInset.bottom);

實現(xiàn)textView的代理方法,下面的代碼方法是當(dāng)textView的text發(fā)生改變時會調(diào)用,我們可以計算文字的高度,調(diào)整backView的高度。

- (void)textViewDidChange:(UITextView *)textView {

NSInteger height = ceilf([self.textView sizeThatFits:CGSizeMake(self.textView.bounds.size.width, MAXFLOAT)].height);

if (_textOldH!=height) {

// 最大高度,可以滾動

self.textView.scrollEnabled = height > _maxTextH && _maxTextH > 0;

if (self.textView.scrollEnabled==NO) {

_backViewHCons.constant = height + 10;//距離上下邊框各為5,所以加10

[self.view layoutIfNeeded];

}

_textOldH = height;

}

}

我們上面講鍵盤的return鍵設(shè)置了樣式是send,所以當(dāng)用戶再點擊return鍵時不應(yīng)該是換行而是實現(xiàn)send的業(yè)務(wù)邏輯,所以需要實現(xiàn)下面的代理。

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{

if (textView==self.textView && [text isEqualToString:@"\n"]){ //判斷輸入的字是否是回車,即按下return

//在這里做你響應(yīng)return鍵的代碼

textView.text = nil;

[self textViewDidChange:textView];

return NO; //這里返回NO,就代表return鍵值失效,即頁面上按下return,不會出現(xiàn)換行,如果為yes,則輸入頁面會換行

}

return YES;

}

總結(jié)一下,這里的關(guān)鍵是當(dāng)textView的字?jǐn)?shù)變化時,我們通過計算得到當(dāng)前字?jǐn)?shù)應(yīng)該顯示的高度,我們得到這個值后適當(dāng)?shù)恼{(diào)增backView的高度,因為backView是相對于底部約束,增加高度后就會向上增加,而textView是依據(jù)backView的頂部與底部來約束的所以就會跟隨者backView的高度變化而變化。從而實現(xiàn)textView自適應(yīng)高度。

這里是demo的下載地址 ,有什么問題歡迎大家指正。另外如果對你有幫助別忘了star。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容