iOS中如何根据输入的文字动态改变textview高度的宽度和高度

1021人阅读
iOS开发(358)
UITextView的高度随着输入文字实时的改变是app中非常常见的功能,社交软件的文字输入框、评论框都会用到
网上有很多UITextView的高度随着输入文字实时改变的demo,笔者看了很多,很多虽然可以实现相应的功能但是有些细节实现的不是很好,所以笔者在参考前人的基础上,做了些许优化,希望能对读者有所帮助
一言不合贴代码:
创建UITextView
self.contentTextView = [[UITextView alloc]initWithFrame:CGRectMake((kMainBoundsWidth-250)/2, kMainBoundsHeight/2-50, 250, 39)];
self.contentTextView .layer.cornerRadius = 4;
self.contentTextView .layer.masksToBounds = YES;
self.contentTextView .delegate = self;
self.contentTextView .layer.borderWidth = 1;
self.contentTextView .font = [UIFont systemFontOfSize:14];
self.contentTextView .layer.borderColor = [[[UIColor lightGrayColor] colorWithAlphaComponent:0.4] CGColor];
self.contentTextView.textContainerInset = UIEdgeInsetsMake(10,0, 0, 0);
[self.view addSubview:self.contentTextView ];
实现的关键:UITextView 的一个代理方法- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
这个代理方法可能很多新手都不太常用,UITextView 每此输入字符都会走该方法,在这个方法中实时计算输入文字的高度,从而动态调整UITextView 的高度是最合适不过的。
1.计算输入文字高度的方法,之所以返回的高度值加22是因为UITextView有一个初始的高度值40,但是输入第一行文字的时候文字高度只有18,所以UITextView的高度会发生变化,效果不太好
- (float) heightForTextView: (UITextView *)textView WithText: (NSString *) strText{
CGSize constraint = CGSizeMake(textView.contentSize.width , CGFLOAT_MAX);
CGRect size = [strText boundingRectWithSize:constraint
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14]}
context:nil];
float textHeight = size.size.height + 22.0;
return textH
2.在- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;中一步步实现我们的效果:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
CGRect frame = textView.frame;
height = [ self heightForTextView:textView WithText:textView.text];
frame.size.height =
[UIView animateWithDuration:0.5 animations:^{
textView.frame =
} completion:nil];
return YES;
如上面一段代码,我们在输入文字的时候实时计算textView中的文字,就可以得到我们想要的高度,效果如何呢?
UITextView01
细心的读者可能发现了,在第二行输入第一个字的时候,frame没有更改,输入第二个字的时候才发生更改,第三行同样如此,什么原因呢?
笔者打断点调试后,终于找到问题的根源,回过头来再看- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)这个方法,可以看到该方法有两个参数textView 和text,在方法我们计算的是textView.text的高度,但实际上这里存在一个问题,每次输入文字后调用该方法,此时输入的文字并不在textView.text中,而在另一个参数text中,走完该方法后每次输入的文字才加入到textView.text中。笔者选择的解决方案是将textView.text和text文字拼接起来
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
CGRect frame = textView.frame;
float height = [self heightForTextView:textView WithText:[NSString stringWithFormat:@&%@%@&,textView.text,text]];
frame.size.height =
[UIView animateWithDuration:0.5 animations:^{
textView.frame =
} completion:nil];
return YES;
再来看下效果:
UITextView02
可以看出,现在满足了我们刚才的要求,在第二行第一次输入的时候,可以更改frame了,但是新的问题又出现了,就是删除字符的时候,当第二行被删光的时候,没有直接计算frame,直到删除第一行某个文字的时候才会计算,这是为什么呢?
笔者调试过后,发现按删除键的时候,text的文字为@&&,每次按删除键,调用该方法的时候,textView.text此时并没有把该字符删掉,所以计算的还是第一行加第二行文字的高度,因此我们可以根据text的内容做条件判断,如果text内容为@&&,我们通过截取字符串的方式手动去掉一个字符
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
CGRect frame = textView.frame;
if ([text isEqual:@&&]) {
height = [ self heightForTextView:textView WithText:[textView.text substringToIndex:[textView.text length] - 1]];
height = [self heightForTextView:textView WithText:[NSString stringWithFormat:@&%@%@&,textView.text,text]];
frame.size.height =
[UIView animateWithDuration:0.5 animations:^{
textView.frame =
} completion:nil];
return YES;
UITextView03
基本上实现了需求,有一个小bug,造成了闪退,textView.text为空的时候,截取字符串会越界造成闪退,加一个条件判断就好了
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
CGRect frame = textView.frame;
if ([text isEqual:@&&]) {
if (![textView.text isEqualToString:@&&]) {
height = [ self heightForTextView:textView WithText:[textView.text substringToIndex:[textView.text length] - 1]];
height = [ self heightForTextView:textView WithText:textView.text];
height = [self heightForTextView:textView WithText:[NSString stringWithFormat:@&%@%@&,textView.text,text]];
frame.size.height =
[UIView animateWithDuration:0.5 animations:^{
textView.frame =
} completion:nil];
return YES;
笔者只是实现了简单的需求,可能很多地方还不够完善,也可能存在bug,欢迎批评,指正,共同交流。
文/Flying_Einstein(简书作者)
原文链接:/p/9e
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:256287次
积分:3307
积分:3307
排名:第8254名
原创:10篇
转载:371篇
评论:55条
(6)(27)(33)(33)(33)(40)(42)(38)(35)(32)(48)(15)(7)IOS7中动态计算UILable的高度
@interface UILabel (ContentSize)
- (CGSize)contentS
#import "UILabel+ContentSize.h"
@implementation UILabel (ContentSize)
- (CGSize)contentSize {
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = self.lineBreakM
paragraphStyle.alignment = self.textA
NSDictionary * attributes = @{NSFontAttributeName : self.font,
NSParagraphStyleAttributeName : paragraphStyle};
CGSize contentSize = [self.text boundingRectWithSize:CGSizeMake(self.frame.size.width, MAXFLOAT)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:attributes
context:nil].
return contentS
这个类是在别人的基础上修改的。
下面是具体的实现:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 20)];
label.font = [UIFont boldSystemFontOfSize:15.0f];
//UILabel的字体大小
label.numberOfLines = 0;
//必须定义这个属性,否则UILabel不会换行
label.textColor = [UIColor whiteColor];
label.textAlignment = NSTextAlignmentL
//文本对齐方式
[label setBackgroundColor:[UIColor redColor]];
label.lineBreakMode = NSLineBreakByWordW
NSLog(@"%d",label.lineBreakMode);
//宽度不变,根据字的多少计算label的高度
NSString *str = @"伴随着张震岳的这首老歌,仿佛我又回到了过去,回到了大学即将分别的日子,带着不舍与迷惘和他们说再见。又是一年毕业季,看着朋友圈各种晒毕业照,毕业旅行照,学士帽漫天的飞舞,各种送别活动在鲜花和掌声中慢慢退去色彩,心里不时充满着各种思念。离开校园整整一年了,每当和别人谈起母校各种自豪,大学生活各种多彩,人生经历各种丰富,其实内心还是留有种种遗憾;四年的蹉跎时光,有人收获了知识,有人收获了人生阅历,还有人收获了爱情,而我收获的只有那纯洁的友谊,兄弟情。
分别整整一年了,还记得那时我们都是多么的不舍,同学情,兄弟情,混合着酒精流到心里,一米八几的大男孩哭的稀里哗啦,拥抱着说再见;之后的我们离开了熟悉的校园,奔赴在各个工作岗位,去体现自己的价值,为生活而忙碌着;一转身,有些人真的就再也不见。
毕业一周年,你们还好吗?工作还顺利吗?学习还顺心吗?一切都回不了头,只能在心里默默地想着你们,希望你们安好。。。";
CGSize size = [str sizeWithFont:label.font constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
//根据计算结果重新设置UILabel的尺寸
[label setFrame:CGRectMake(20, 10, 280, size.height)];
label.text =
label.text =
[label setFrame: CGRectMake(20, 20, 280, [label contentSize].height)];
[self.view addSubview:label];
上面的注释部分是老的方法。
这里要注意几点:
1、我在调用contentSize前设置下label.lineBreakMode属性。
2、文字到底换不换行的关键是设置CGSizeMake(w,h),区别主要在w,h的值修改。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'不知道的肯定以为是影视学院的学生在拍戏呢。
新郎的衣服已经被撕开,双脚也被透明胶带捆住了。
声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
  ▲点击上方“CocoaChina”关注即可免费学习 iOS 开发
  作者:峥吖
  原文链接:/p/55d98e8f3e61
  Demo效果
  Demo演示:
  1. 添加底部View,到最底部
  底部View都是显示到最下面,并且都是固定死的,采用Xib或者storyboard搭建
  2. 搭建底部View
  3. 拖线
  3.1 获取底部View距离底部的约束,做键盘弹出效果,底部View随着键盘弹出,而往上移动效果
  // 监听键盘弹出
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
  // 键盘弹出会调用
  - (void)keyboardWillChangeFrame:(NSNotification *)note
  // 获取键盘frame
  CGRect endFrame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
  // 获取键盘弹出时长
  CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
  // 修改底部视图距离底部的间距
  _bottomCons.constant = _bottomCons.constant == 0?endFrame.size.height:0;
  // 约束动画
  [UIView animateWithDuration:duration animations:^{
  [self.view layoutIfNeeded];
  3.2 获取底部View高度的约束,当文字修改,去修改底部View整体高度
  3.3 获取文本框输入框
  4.监听文本输入框,文字高度改变
  修改底部高度约束就好了
  // 监听文本框文字高度改变
  _inputView.yz_textHeightChangeBlock = ^(NSString *text,CGFloat textHeight){
  // 文本框文字高度改变会自动执行这个block,修改底部View的高度
  // 设置底部条的高度 = 文字高度 + textView距离上下间距高度(10 = 上(5)下(5)间距总和)
  _bottomHCons.constant = textHeight + 10;
  点击这下载源代码
  热门文章神解释:向外行介绍程序员工作的复杂程度
  史上最坑程序员,把整个公司删没了
  据说,年薪百万的程序员,都是这么开悟的
  知道这20个正则表达式,能让你少写1000行代码
  程序员“从入门到跑路”全系列畅销书,欢迎阅读!
  你在公司项目里面看到过哪些操蛋的代码?
  资深程序员是如何用五年时间攒够100万的
  不懂技术的人不要对懂技术的人说这很容易实现
  史上最内涵的程序员笑话,你能看懂几个?
  GitHub 中国区前 100 名到底是什么样的人?
  微信号: CocoaChinabbs
  ▲长按二维码“识别”关注即可免费学习 iOS 开发
  月薪十万、出任CEO、赢娶白富美、走上人生巅峰不是梦
  --------------------------------------
  投稿邮箱:
欢迎举报抄袭、转载、暴力色情及含有欺诈和虚假信息的不良文章。
请先登录再操作
请先登录再操作
微信扫一扫分享至朋友圈
搜狐公众平台官方账号
生活时尚&搭配博主 /生活时尚自媒体 /时尚类书籍作者
搜狐网教育频道官方账号
全球最大华文占星网站-专业研究星座命理及测算服务机构
主演:黄晓明/陈乔恩/乔任梁/谢君豪/吕佳容/戚迹
主演:陈晓/陈妍希/张馨予/杨明娜/毛晓彤/孙耀琦
主演:陈键锋/李依晓/张迪/郑亦桐/张明明/何彦霓
主演:尚格?云顿/乔?弗拉尼甘/Bianca Bree
主演:艾斯?库珀/ 查宁?塔图姆/ 乔纳?希尔
baby14岁写真曝光
李冰冰向成龙撒娇争宠
李湘遭闺蜜曝光旧爱
美女模特教老板走秀
曝搬砖男神奇葩择偶观
柳岩被迫成赚钱工具
大屁小P虐心恋
匆匆那年大结局
乔杉遭粉丝骚扰
男闺蜜的尴尬初夜
客服热线:86-10-
客服邮箱:&&国之画&&&& &&
版权所有 京ICP备号-2
迷上了代码!

我要回帖

更多关于 动态改变textview高度 的文章

 

随机推荐