• Stars
    star
    129
  • Rank 279,262 (Top 6 %)
  • Language
    Objective-C
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

一个比较完美的高度自适应输入框。

iOS 一个比较完美的 Growing TextView(高度自适应输入框)

GrowTextView

CI Status Version License Platform

缘由

现在都 2019 年了,App 中使用自动增高的输入框已经很常见了,即时通讯的 Chat 界面、社交类 App 的评论功能都可以看到自增高输入框。但写出一个自增高输入框容易,写好难。现在市面上一些主流 App 的输入框依然会有一些瑕疵,例如:文字挡住一部分、粘贴大量文字时出现偏移,具体问题下面详细分析。

现在 iOS 开发已经过了搭建 UI 和普通业务功能的初级阶段,App 要想赢得用户的青睐,除了 App 的功能、UI 设计,交互体验的细节处理至关重要。一般用户只要使用输入框能正常输入即可,90% 的用户不会察觉输入框的一些细节,但作为开发人员应该知道这些细节(bug)并做出处理。

主流 App 的输入框之痛

粘贴文本出现文字偏移

这个问题严格来说算 bug,毕竟粘贴还是一个很常见的操作。

粘贴文本出现文字偏移

挡住部分文字

这个问题对 App 功能没有任何影响,但这么多 App 竟然都有这个问题而且非常普遍,是我始料未及的。测试了多个 App 后,只有QQ的输入框做的最好,粘贴、遮挡文字等问题根本不存在。

1_zhiHu_cover.PNG weiBo_cover.PNG touTiao_cover.PNG jd_cover.PNG weixin_cover.png

比较完美的输入框

写出一个自增高的输入框还是比较容易的,大致过程就是给 textView 添加左、右、下/上、高度四个约束,然后监听文字变化的通知,进而修改输入框的高度。我接下来主要说一下大家可能遇到的一些细节问题。

1、粘贴文本,文字偏移

我的做法是继承 UITextView 重写 setBounds 方法,重新调整contentOffset

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];
    //    NSLog(@"bounds:%@", NSStringFromCGRect(bounds));
    if (self.contentSize.height <= self.bounds.size.height + 1){
        self.contentOffset = CGPointZero; // Fix wrong contentOfset
    } else if (!self.tracking) {
        CGPoint offset = self.contentOffset;
        if (offset.y  > self.contentSize.height - bounds.size.height) {
            offset.y = self.contentSize.height - bounds.size.height;
            if (!self.decelerating && !self.tracking && !self.dragging) {
                self.contentOffset = offset;
            }
            // Fix wrong contentOfset when paster huge text
        }
    }
}

2、文字离输入框顶部间隙时大时小

正常情况下滚动输入框的文字,文字可以滚动到控件顶部。而 QQ 的输入框,不管怎么滑动文字,文字和输入框顶部都有一段固定间隔。

QQ_Top_margin

先了解输入框的一个属性textContainerInset,这个值默认是 (8, 0, 8, 0),就是说默认情况下文字和输入框顶部有 8pt 的偏移,所以当文字输入较多的时候文字向上滚动,那么文字和控件顶部间隙会减小到 0。

实现QQ输入框的效果,我能想到的方案是把textContainerInset全设置为 0(或者top/bottom为0),这样文字就紧挨着输入框,文字和输入框顶部的固定间距就是 0 了。接着要给UITextView 添加一个 containerViewcontainerView 竖向比 UITextView 高出一部分,从而实现 顶部/底部 的固定间距。

3、挡住部分文字

这个问题是因为 单行文字高度 * 最大行数 != 输入框的最大高度,输入框的最大高度可不是随便设置的,先确定输入框的font和最大行数,font.lineHeight * 行数就是输入框的最大高度。这样就不会出现文字挡住一部分的问题了

GrowTextView

接下来就是我自己写的自增高输入框了,目前没发现什么问题,至少没有上面涉及的问题。

[Reference]

Requirements

  • ARC

Installation

Manual

Add JLTextContentView.h/m and JLTextView.h/m to your project.

Cocoapods. [Recommand]

Base is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'GrowTextView', '~> 1.0'

Author

wuzhenli, [email protected]

License

GrowTextView is available under the MIT license. See the LICENSE file for more info.