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

时间:2022-06-20 18:04:57

代码地址如下:
http://www.demodashi.com/demo/13210.html

前言

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

具体效果

运行效果图

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

实现过程

我的思路是用约束来实现,输入区域用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距离底部的约束都拉到代码中成为属性。

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

在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:self

selector:@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大师代发,拒绝转载,转载需要作者授权

iOS即时通讯输入框随字数自适应高度的更多相关文章

  1. iOS 即时通讯,从入门到 “放弃”?

    原文链接:http://www.jianshu.com/p/2dbb360886a8 本文会用实例的方式,将 iOS 各种 IM 的方案都简单的实现一遍.并且提供一些选型.实现细节以及优化的建议. — ...

  2. iOS即时通讯之CocoaAsyncSocket源码解析三

    原文 前言 本文实例Github地址:即时通讯的数据粘包.断包处理实例. 本文旨以实例的方式,使用CocoaAsyncSocket这个框架进行数据封包和拆包.来解决频繁的数据发送下,导致的数据粘包.以 ...

  3. iOS即时通讯之CocoaAsyncSocket源码解析五

    接上篇:iOS即时通讯之CocoaAsyncSocket源码解析四         原文 前言: 本文为CocoaAsyncSocket Read篇终,将重点涉及该框架是如何利用缓冲区对数据进行读取. ...

  4. iOS即时通讯之CocoaAsyncSocket源码解析四

    原文 前言: 本文为CocoaAsyncSocket源码系列中第二篇:Read篇,将重点涉及该框架是如何利用缓冲区对数据进行读取.以及各种情况下的数据包处理,其中还包括普通的.和基于TLS的不同读取操 ...

  5. iOS即时通讯之CocoaAsyncSocket源码解析二

    原文 前言 本文承接上文:iOS即时通讯之CocoaAsyncSocket源码解析一 上文我们提到了GCDAsyncSocket的初始化,以及最终connect之前的准备工作,包括一些错误检查:本机地 ...

  6. iOS即时通讯之CocoaAsyncSocket源码解析一

    申明:本文内容属于转载整理,原文连接 前言: CocoaAsyncSocket是谷歌的开发者,基于BSD-Socket写的一个IM框架,它给Mac和iOS提供了易于使用的.强大的异步套接字库,向上封装 ...

  7. iOS 即时通讯 + 仿微信聊天框架 + 源码

    这些你造吗? 即时通讯(IM),在IOS这片江湖里面已经算是一个老者了,我这小旋风也是在很早以前巡山的时候,就知道有即时通讯这个妖怪,以前也多多少少接触过一些,在造APP的时候用过,哎呀,说着说着就感 ...

  8. iOS:即时通讯之<了解篇 SocKet>

    什么是socket? 计算机专业术语就是: 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket.Socket的英文原义是“孔”或“插座”.作为BSD UNIX的进 ...

  9. iOS 设置UILabel的行间距并自适应高度

    NSString *contentStr = @"总以为,在最初的地方,有一个最原来的我,就也会有一个最原来的你"; UILabel *tempLabel = [[UILabel ...

随机推荐

  1. [Android新手区] SQLite 操作详解--SQL语法

    该文章完全摘自转自:北大青鸟[Android新手区] SQLite 操作详解--SQL语法  :http://home.bdqn.cn/thread-49363-1-1.html SQLite库可以解 ...

  2. Eclipse启动tomcat时报错:Multiple Contexts have a path of "/xxx"

    今天使用Eclipse启动tomcat部署项目时,遇到一个奇怪的错误: Could not publish server configuration for Tomcat v6.0 Server at ...

  3. Golang之AES/DES加密解密

    AES/DES加密/解密涉及4个概念:1. Block, 也叫分组, 相应加密/解密的算法. 2. BlockMode, 模式, 相应加密/解密的处理.3. InitalVectory, 初始向量4. ...

  4. grep线上环境精典案例后续

    请执行命令取出 linux 中 eth0 的 IP 地址(请用 cut,有能力者也可分别用 awk,sed 命令答). 自己的方法: [root@nginx_back ~]# ifconfig eth ...

  5. jQuery插件开发 格式与解析

    jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery命名空间的函数,另一种是对象级 ...

  6. hdu 1059 Dividing 多重背包

    点击打开链接链接 Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  7. ajax调用数据案例,二级联动

    题目:请针对移动端web浏览器制作一个结账数据信息展示页面 要求: 1. 页面样式除不使用表格呈现外,可*选择其他呈现方式 2. 需符合移动端操作习惯 3. 可根据服务区.门店查询结账信息 4. 可 ...

  8. TCP/IP协议复习

  9. LOB对象在数据泵导出、导入后查询对象数量发现丢失

    问题描述:问题:源库的某个Schema使用数据泵Expdp元数据整体导出,在目标库导入且成功后,逻辑验证用户对象,发现缺失.分析查询后,缺失的对象,都是LOB类型(并不是所有的LOB都无法导入,是大部 ...

  10. Windows守护进程简单示例

    转载: https://blog.csdn.net/kikaylee/article/details/51395360 /* @描述:一个简单的Windows守护进程的例子(C++版本) @作者:ki ...