美文网首页UI效果iOS技术专题iOS常见的一些界面demo
UITextView输入时高度自适应(优化增强版)

UITextView输入时高度自适应(优化增强版)

作者: 横爬介士 | 来源:发表于2016-09-10 17:55 被阅读4970次

    接上篇这段时间比较忙,说好的给写一个UITextView的demo,但是无奈一直没有时间,今天终于抽时间完成了,基本要求的功能都具备。

    1.png

    首先回答一下@RicoCL的问题,一眨眼已经将近40天了,实在是不好意思,其实原理很简单,只要在当前文字高度 >= textView最大高度时,将textView的scrollEnable设置为YES即可,删除时,在当前文字高度 < textView最大高度时,设置为NO即可。

    效果图镇楼

    输入框效果图.gif

    1 需求分析

    平时经常用到UITextView时,经常会有这么几个问题:

    • placeholder的设置
    • placeholder字体颜色的设置
    • placeholder字体大小的设置
    • 圆角以及边框的设置
    • UITextView行数限制,达到最大高度时,可以滚动查看之前内容
    • UITextView输入时高度自适应,包括输入以及删除时
    • UITextView常常不是单独出现,例如微信输入框右侧的声音按钮,+号按钮等等。
    针对上面的几个需求,逐一分析:
    • 其中placeholder的相关属性(placeholder,字体颜色,字体大小)是通过在另外一个大小相等的UITextView *placeholderView的相关属性实现的,同等大小的_placeholderView可以完美的与之重合,是设置作为设置placeholderView最好选择。重写公有属性的setter方法,设置_placeholderView的相关属性
    • 圆角以及边框设置通过layer属性实现;
    • UItextView文本最大行数公开属性,供外界调用。高度自适应,给UITextView设置监听,监听方法根据文本内容动态决定UITextView是否可以滚动。需求中因为UITextView常常不是单独出现,父视图有可能是一个View,并在父视图之间设置间距以及约束,因此设置一个block动态的根据需求改变父视图的高度。

    2 代码展示

    demo中的注释比较项目,有需要的可以直接调至文末直接下载。
    CMInputView.h文件

    #import <UIKit/UIKit.h>
    
    typedef void(^CM_textHeightChangedBlock)(NSString *text,CGFloat textHeight);
    
    @interface CMInputView : UITextView
    
    /**
     *  占位文字
     */
    @property (nonatomic, strong) NSString *placeholder;
    
    /**
     *  占位文字颜色
     */
    @property (nonatomic, strong) UIColor *placeholderColor;
    
    /**
     *  占位符字体大小
     */
    @property (nonatomic,strong) UIFont *placeholderFont;
    
    /**
     *  textView最大行数
     */
    @property (nonatomic, assign) NSUInteger maxNumberOfLines;
    
    /**
     *  文字高度改变block → 文字高度改变会自动调用
     *  block参数(text) → 文字内容
     *  block参数(textHeight) → 文字高度
     */
    @property (nonatomic, strong) CM_textHeightChangedBlock textChangedBlock;
    /**
     *  设置圆角
     */
    @property (nonatomic, assign) NSUInteger cornerRadius;
    
    - (void)textValueDidChanged:(CM_textHeightChangedBlock)block;
    
    @end
    
    

    CMTextView.m文件中核心代码的实现

    - (void)textDidChange
    {
        // 根据文字内容决定placeholderView是否隐藏
        self.placeholderView.hidden = self.text.length > 0;
        
        NSInteger height = ceilf([self sizeThatFits:CGSizeMake(self.bounds.size.width, MAXFLOAT)].height);
        
        if (_textH != height) { // 高度不一样,就改变了高度
            
            // 当高度大于最大高度时,需要滚动
            self.scrollEnabled = height > _maxTextH && _maxTextH > 0;
            
            _textH = height;
            
            //当不可以滚动(即 <= 最大高度)时,传值改变textView高度
            if (_textChangedBlock && self.scrollEnabled == NO) {
                _textChangedBlock(self.text,height);
                
                [self.superview layoutIfNeeded];
                self.placeholderView.frame = self.bounds;
    
            }
        }
    }
    

    3 使用注意

    _placeholderView的初始化是在_placeholder的setter方法中实现的,其中font的设置是与UITextViewfont是同等大小的,因此placeholder属性的设置需要在设置UITextViewfont之后才会生效,否则为系统默认字体大小;当然,不需要先后顺序,通过placeholderFont属性的设置也可以实现。

    Demo下载 请戳这里 欢迎star

    相关文章

      网友评论

      • Hsusue:重新设置frame导致输入框被键盘挡住了 有方法解决吗
      • liusong007:源码以下问题
        1.无法使用masory xib StoryBoard;
        2.如果用了masory那么占位符 一进来的时候没有占位符,用户编辑的时候才有占位符 且无法消除
        3.如果是其它界面传过来的数据,那么占位符还在, 且无法进行自适应行高 4.无法设置内容垂直居中
        5.从其它界面进来的时候回传数据的时候占位符还在

        本来一个问题,用了控件之后带来五个问题:joy:
      • Gxpzy:问题: 如果使用代码设置text的话,CMTextView 没有接收到通知,因此block也就没有调用。
      • First灬DKS:我运行demo就没有效果呢,在输入了4行以后,下面输入的就不显示了;也不可以滑动;
      • PGOne爱吃饺子:楼主的设置最大高度好像没有什么用处啊
      • PGOne爱吃饺子:楼主 你好 请问你的这个 maxNumberOfLines 属性是干什么用的
      • 旅行的光:为什么我将scrollenable设置为NO,高度不能自动变化,只有是yes时才可以?
        横爬介士:@AC_xiaobai 这段时间项目比较忙,每天十一点。。。唉

        横爬介士:这段时间项目比较忙,抽时间我优化一下子,多谢提bug
        f24e9d691049:我也是 好尴尬~~
      • 麦子maizi:模拟机6Plus测试,达到max行数4后,上面文字有小部分会被遮挡,还有删除后,上面也会被遮挡,可以解决吗。
      • Zzzzzed丶Van:你好,请问删除时的高度适应怎么设置
        横爬介士:这是size的时候将高度固定,宽度设置为maxfloat
      • __阳阳:写的不错, 已star
        横爬介士:嗯嗯,多谢鼓励
      • 季末微夏:打开Demo第一眼就看到block循环引用
        ```
        // 设置文本框最大行数
        __weak __typeof(self) weakSelf = self;
        [_inputView textValueDidChanged:^(NSString *text, CGFloat textHeight) {
        __typeof(&*weakSelf) strongSelf = weakSelf;
        CGRect frame = strongSelf.inputView.frame;
        frame.size.height = textHeight;
        strongSelf.inputView.frame = frame;
        }];

        ```
        季末微夏:@横爬介士 https://github.com/JmoVxia/CMInputViewTest 这是测试Demo,自己看就知道了
        横爬介士:我相信你百度完了以后就不会说这是循环引用了
        横爬介士:建议你看一下weak strong dance
      • 37c495f2510b:textView 如果放在scrollerview上自适应高度,每次增加高度的时候scrollview也会移动,解决不了啊
      • 嘞似彩笔:写得挺不错的 ~ 但是 iOS8.4 到最大高度后居然无法换行。。 也不能滚动,。不知道是什么原因。。我也看了。。改变文字时高度这些都是对的,但是他就是不显示 - - 好神奇。。。
        横爬介士:@LittleBitch_x 这个8.4的系统说实话,还真是没有遇到哈,不过,解决了就好,多谢
        嘞似彩笔:// 当高度大于最大高度时,需要滚动
        BOOL isChange = !self.scrollEnabled;
        self.scrollEnabled = height > _maxTextH && _maxTextH > 0;
        if (self.scrollEnabled && isChange) {
        self.contentOffset = CGPointMake(0,1);
        }
        在这里加了一句- - 用代码改变一下他的contentOffset
        嘞似彩笔:@LittleBitch_x 恩 解决了。。 8.4真的是个神奇的系统。。。

      本文标题:UITextView输入时高度自适应(优化增强版)

      本文链接:https://www.haomeiwen.com/subject/dlnyettx.html