美文网首页
TextView占位符,随着字符串长度自动增高

TextView占位符,随着字符串长度自动增高

作者: tangbin583085 | 来源:发表于2017-09-09 15:56 被阅读0次

    开发这个控件的缘由是因为目前做的App有一个对话框的功能,而苹果提供的原生UITextField或者UITextView不符合对话框的需求(该控件可用于对话输入框)。

    限制
    1,UITextFiled不能多行输入
    2,UITextView没有占位符
    3,2者都不能自动增高功能。

    重写UITextView

    1,为UITextView添加占位符

    - (UITextView *)placeHolder {
        if (_placeHolder == nil) {
            UITextView *placeHolder = [[UITextView alloc] init];
            _placeHolder = placeHolder;
            placeHolder.userInteractionEnabled = NO;
            placeHolder.showsVerticalScrollIndicator = NO;
            placeHolder.showsHorizontalScrollIndicator = NO;
            placeHolder.scrollEnabled = NO;
            placeHolder.font = self.font;
            placeHolder.backgroundColor= [UIColor clearColor];
            placeHolder.textColor = [UIColor lightGrayColor];
            [self addSubview:placeHolder];
        }
        return _placeHolder;
    }
    

    监听文本变化显示或隐藏占位符

    - (instancetype)init {
        if (self = [super init]) {
            // 添加文本变化通知
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeText:) name:UITextViewTextDidChangeNotification object:nil];
        }
        return self;
    }
    

    2,处理文本变化
    自定义方法 didChangeText,比如显示隐藏站位文本,根据字符串计算最新高度

    - (void)didChangeText:(NSNotification *)notification{
        
        // 隐藏显示占位符
        self.scrollEnabled = self.placeHolder.hidden = self.hasText;
        
        // 以防监听到非自己的文本变化
        TBTextView *textView = notification.object;
        if (textView == nil || textView != self || !self.tbDelegate || ![self.tbDelegate respondsToSelector:@selector(changeHeight:textString:textView:)]) return;
    
        // 计算宽高
        CGFloat height = [self.text boundingRectWithSize:CGSizeMake(self.frame.size.width - 10, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.font} context:nil].size.height + 0.5;// 加0.5以防显示不全 -10是因为输入框左右有边距
    
        // 记录初始化高度
        static BOOL firstTimeIn = YES;
        if (firstTimeIn) {
            firstTimeIn = NO;
            _initHeight = self.bounds.size.height;
        }
        
        // 为什么取整?  因为有晃动的情况出现
        NSInteger heigtInt = ceil(height);
        CGFloat curHeight = heigtInt + self.textContainerInset.top + self.textContainerInset.bottom;
        
        // 当前高度比原始高度小
        if (_initHeight > curHeight) {
            curHeight = _initHeight;
        }
        
        // 不能超过最大高度
        if (_maxLine > 0 && curHeight > _maxHeight ) {
            curHeight = _maxHeight;
            self.scrollEnabled = YES;
        }else{
            self.scrollEnabled = NO;
        }
        
        // 执行代理
        if ([self.tbDelegate respondsToSelector:@selector(changeHeight:textString:textView:)]) {
            [self.tbDelegate changeHeight:curHeight textString:textView.text textView:textView];
        }
    }
    

    3,代理返回新高度

        // 执行代理
        if ([self.tbDelegate respondsToSelector:@selector(changeHeight:textString:textView:)]) {
            [self.tbDelegate changeHeight:curHeight textString:textView.text textView:textView];
        }
    

    有些小细节需要注意下:
    1,为什么用 UITextView 作占位符而不用UILabel,是因为UITextView可以与本身文字可以重叠一致
    2,UITextView的上下有textContainerInset
    3, 为什么取整? 因为有抖动的情况出现
    NSInteger heigtInt = ceil(height);
    CGFloat curHeight = heigtInt + self.textContainerInset.top + self.textContainerInset.bottom;


    相关文章

      网友评论

          本文标题:TextView占位符,随着字符串长度自动增高

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