[iOS] 输入框高度随输入内容变化

实现这个效果的关键点只有两点:

  1. 获取正在输入内容在UITextView占用了多少行
  2. UITextView动态改变大小

一开始,为了解决第一个问题,我一直在考虑怎么获取换行事件,发现只用捕捉\n输入即可,但这样又有一个麻烦,就是删除行怎么办?所以感觉这个思路太麻烦

对于第一点,有一个方便的计算方法,就是获取UITextView内容的高度比上UITextView的字体的高度,即可得到当前的行数。

这里有一个技巧,那就是不要用UITextViewbound.size.height获取其高度,因为这个获取的高度跟你输入的文字总高度并没有任何关系。

要知道,UITextView是继承UIScrollView的。

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITextView : UIScrollView <UITextInput>

这一点你可以不知道,但根据平时的操作经验,一个UITextView输入文字过多时是可以用手上下拖动浏览内容的,所以可以猜想是和UIScrollView有关系。

另一个类似的输入框UITextField不支持换行哦,设置什么lineBreakMode啊,lineNumber(好像没这个属性)啊都不可以换行!我以前在这上面栽过跟头。UITextField输入满了会把文字顶到前面看不见的地方,但还不支持左右拖动!这一点比Android体验要差!

好了,知道其集成UIScrollView就好办了,因为UITextView只有在输入内容超过其显示范围才可以拖动,那就知道输入文字的bound就是UIScrollViewcontentSize。这样就知道输入内容的总大小了。

那每一行的高度呢?

按我以前的经验,行高差不多是字体大小的 4/3 倍.这样设值显示效果一般都挺好。所以可以设值一个宏定义来处理与字体相关的高度。

当然,我的经验是因为过去没有这方面经验的笨办法,正确的办法是使用FontlineHeight属性:

// The height of text lines (measured in points). (read-only)
@property(nonatomic,readonly)        CGFloat   lineHeight NS_AVAILABLE_IOS(4_0);

OK,知道每行的高度,就可以计算当前有多少行文字了,在

- (void)textViewDidChange:(UITextView *)textView

代理方法中计算高度即可。

对于第二点,根据计算出的高度重绘界面布局即可。这里我用的是自动布局,每次高度改变就刷新布局关系就行。下面放部分代码:

我把输入框和一些其他组件封装为一个控件,在类中声明代理:

@protocol EssayEditDelegate <NSObject>

@optional
- (void) onTextViewLineCountChangeTo:(NSInteger)lines;

@end

在每次输入内容的时候计算行数,声明一个变量保存上一次的行数,两次行数不一致即为发生换行

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

    NSInteger numLines = textView.contentSize.height / textView.font.lineHeight;
    if (numLines != rows) {
        rows = numLines;
        //发生换行
        if (_delegate && [_delegate respondsToSelector:@selector(onTextViewLineCountChangeTo:)]) {
            [_delegate onTextViewLineCountChangeTo:rows];
        }
    }

	......
}

在外部实现代理方法,更新界面

#pragma mark - Essay delegate
- (void)onTextViewLineCountChangeTo:(NSInteger)lines {
    rowCount = lines;
    [self remakeConstraint];
}

- (void)remakeConstraint {
    NSInteger toobarHeight;
    NSInteger rows = rowCount > DEFAULT_ROW_COUNT ? rowCount : DEFAULT_ROW_COUNT;
    toobarHeight = (ESSAY_EDIT_FONT_SIZE / 2 * 3) * rows + MARGIN_BUTTON * 2;

    [toolBarView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.bottom.right.equalTo(self);
        make.top.equalTo(quesImageView.mas_bottom);
        make.height.mas_equalTo(toobarHeight);
    }];
}

reference How to Read Number of lines in UITextView

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术总结

UIkit Dynamics 投掷效果

2155
来自专栏AndroidTv

属性动画 ValueAnimator 运行原理全解析

好,废话不多说,之前我们已经分析过 View 动画 Animation 运行原理解析,那么这次就来学习下属性动画的运行原理。

4288
来自专栏hightopo

原 荐 基于HTML5 Canvas的工控S

1243
来自专栏数据的力量

10个提高你工作效率的Excel技巧

3024
来自专栏Google Dart

Flutte部件目录-基本部件(一)

一个容器首先用padding包围子组件(由decoration中出现的所有边框填满),然后将附加constraints应用于填充范围(将width和height...

3872
来自专栏美团技术团队

Android硬件加速原理与实现简介

在手机客户端尤其是Android应用的开发过程中,我们经常会接触到“硬件加速”这个词。由于操作系统对底层软硬件封装非常完善,上层软件开发者往往对硬件加速的底层原...

4455
来自专栏简书专栏

基于turtle的Python作画

pendown()的作用是落笔,只有落笔才能作画。 当不作画却想移动画笔的时候要提笔,用函数penup() forward是画笔向前移动,函数当中参数为移动...

5581
来自专栏DannyHoo的专栏

iOS开发中去掉tabBar上方的一条横线

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

3274
来自专栏向治洪

Android硬件加速介绍与实现

概述 在手机客户端尤其是Android应用的开发过程中,我们经常会接触到“硬件加速”这个词。由于操作系统对底层软硬件封装非常完善,上层软件开发者往往对硬件加速的...

3348
来自专栏Android机动车

Android中的Vector

随着 Android 的碎片化越来越严重,适配成为一个开发中一个痛点。如果 UI 只切一套图,但是在一些特定机型上难免会出现模糊或者变形的情况,如果切多套不同分...

1494

扫码关注云+社区

领取腾讯云代金券