博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS即时通讯输入框随字数自适应高度
阅读量:6586 次
发布时间:2019-06-24

本文共 3531 字,大约阅读时间需要 11 分钟。

代码地址如下:

http://www.demodashi.com/demo/13210.html

前言

本人最近在研究socket与聊天界面的UI,在写聊天界面UI的时候是模仿微信的界面其中的文字输入框会随着字数的多少而自适应高度,当然超过某个行数输入框的高度就不会增加了变为可滚动,

具体效果

运行效果图

f1Kpa8y5XBLqD8hzajc.gif

实现过程

我的思路是用约束来实现,输入区域用UITextView来实现;约束可以使用AutoLayout或者是第三方库Masonry来实现,但是他们的实现原理是一样的。为了方便我使用了Xib加AutoLayout来实现的,我是根据UITextView的字数,宽度固定来计算出文字的高度,从而实现UITextView的高度自适应。

我们都知道一般的聊天软件的界面(微信为例)输入框左边是一个按钮切换语音或者文字,输入框右边是表情符号和切换出发送照片等功能;当然本文主要是介绍输入框TextView的自适应,原谅我把其他东西省略了。首先textView需要一个BackVew,我们拖进去一个UIview,让它相对于父视图居左居右为0,居底部也为0,另外还需要给它一个初始高度,一般情况下是textView是一行文字的高度+textView距离它的顶部距离和底部距离。比如,我让textView距离它的backView底部与顶部分别是5,textView的字号是系统17号字,那么textView是一行的时候它的高度就是37,而这时候backView的初始高度就是37+5+5=47。textView居底部与顶部分别是5,距离左右的具体可以根据你们设计给的UI而定。这里的关键是当textView的字数变化时,我们通过计算得到当前字数应该显示的高度,我们得到这个值后适当的调增backView的高度,因为backView是相对于底部约束,增加高度后就会向上增加,而textView是依据backView的顶部与底部来约束的所以就会跟随者backView的高度变化而变化。从而实现textView自适应高度。

完后上面的约束之后,我们需要把backView、textView、backView的高度约束以及backView距离底部的约束都拉到代码中成为属性。

FhCWN6Y0FuFoF5AEKQ3.png

在viewdidload方法里面实现textView的一些设置

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];//当textview的字符串为0时发送(rerurn)键无效self.textView.enablesReturnKeyAutomatically = YES;self.textView.keyboardType = UIKeyboardTypeDefault;//键盘return样式变成发送self.textView.returnKeyType = UIReturnKeySend;

当键盘升起的时候我们需要调整backView具体底部的距离,防止键盘升起遮挡textView,所以要实现监听键盘高度

//监听键盘[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(keyboardWasShown:)name:UIKeyboardWillChangeFrameNotification object:nil];

实现当键盘升起或者落下的方法

- (void)keyboardWasShown:(NSNotification*)aNotification {// 获取键盘弹出时长CGFloat duration = [aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];//键盘高度CGRect keyBoardFrame = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];CGFloat screenH = [UIScreen mainScreen].bounds.size.height;//调增backView距离父视图底部的距离_backViewBottomHCons.constant = keyBoardFrame.origin.y != screenH?keyBoardFrame.size.height:0;[UIView animateWithDuration:duration animations:^{[self.view layoutIfNeeded];}];}

设置textView的最大高度,这个与你设置的最大行数有关

// 计算最大高度 = (每行高度 * 总行数 + 文字上下间距)_maxTextH = ceil(self.textView.font.lineHeight * 4 + self.textView.textContainerInset.top + self.textView.textContainerInset.bottom);

实现textView的代理方法,下面的代码方法是当textView的text发生改变时会调用,我们可以计算文字的高度,调整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键设置了样式是send,所以当用户再点击return键时不应该是换行而是实现send的业务逻辑,所以需要实现下面的代理。

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{if (textView==self.textView && [text isEqualToString:@"\n"]){ //判断输入的字是否是回车,即按下return//在这里做你响应return键的代码textView.text = nil;[self textViewDidChange:textView];return NO; //这里返回NO,就代表return键值失效,即页面上按下return,不会出现换行,如果为yes,则输入页面会换行}return YES;}

总结一下,这里的关键是当textView的字数变化时,我们通过计算得到当前字数应该显示的高度,我们得到这个值后适当的调增backView的高度,因为backView是相对于底部约束,增加高度后就会向上增加,而textView是依据backView的顶部与底部来约束的所以就会跟随者backView的高度变化而变化。从而实现textView自适应高度。

补充

暂时没有

iOS即时通讯输入框随字数自适应高度

代码地址如下:

http://www.demodashi.com/demo/13210.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

你可能感兴趣的文章
sumk 2.0.0 发布,轻量级互联网框架
查看>>
高性能web建站规则(将js放在页面底部)
查看>>
办公用品管理系统VB——模块
查看>>
AI2XAML's Bug
查看>>
Linux系统下apt-get命令详解
查看>>
OpenCV 尺度不变特征检测:SIFT、SURF、BRISK、ORB
查看>>
React学习笔记—表单
查看>>
Java EnumMap工作原理及实现
查看>>
GNOME 3.32.1 维护版本更新发布
查看>>
阐述Spring框架中Bean的生命周期?
查看>>
虚拟内存管理
查看>>
注水、占坑、瞎掰:起底机器学习学术圈的那些“伪科学”
查看>>
大数据小视角1:从行存储到RCFile
查看>>
JavaScript常用设计模式
查看>>
第18天:京东网页头部制作
查看>>
Android RecyclerView批量更新notifyItemRangeChanged
查看>>
好消息:Dubbo & Spring Boot要来了
查看>>
面向对象封装的web服务器
查看>>
pytorch新手需要注意的隐晦操作Tensor,max,gather
查看>>
开启“互联网+”模式打造智能移动APP巡检系统
查看>>