关于UITextView的封装

目前能够实现的功能:

  1. 设置占位字符,可以设置占位字符的字体大小,字体颜色,字体高亮颜色,也可以设置属性字符串作为占位字符
  2. 设置最大行数,超过最大行数之后滚动显示
  3. 设置最多输入的文字个数,超过之后不能输入,并触发block回调
  4. 设置输入框的圆角弧度
  5. 设置光标的宽度和高度

直接上代码:

.h文件:

//
//  KPTextView.h
//
//  使用时至少实现 占位文字内容 和 文字的字体大小
//
//  Created by 刘鲲鹏 on 2017/5/12.
//  Copyright © 2017年 刘鲲鹏. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef void(^KP_textHeightChangedBlock)(NSString *text,CGFloat textHeight);

typedef void(^KP_textViewLengthOverLimitBlock)(NSInteger maxLengthOfText);

@interface KPTextView : UITextView


/**
 *  普通字符串 占位文字
 */
@property (nonatomic, strong) NSString *placeholder;

/**
 *  属性字符串 占位文字
 */
@property (nonatomic, strong) NSAttributedString *attributedPlaceHolder;

/**
 *  占位文字颜色,默认为亮灰色
 */
@property (nonatomic, strong) UIColor *placeholderColor;

/**
 *  占位文字高亮颜色,默认为亮灰色
 */
@property (nonatomic, strong) UIColor *placeholderHighLightColor;

/**
 *  占位符字体大小
 */
@property (nonatomic,strong) UIFont *placeholderFont;

/**
 *  textView最大行数,默认没有高度限制
 */
@property (nonatomic, assign) NSUInteger maxNumberOfLines;

/**
 *  textView可以输入的最大字数,默认没有字数限制
 */
@property (nonatomic, assign) NSUInteger maxLengthOfText;

/**
 *  设置边框宽度,默认为1
 */
@property (nonatomic, assign) NSUInteger borderWidth;

/**
 *  设置边框颜色,默认为亮灰色
 */
@property (nonatomic, strong) UIColor *borderColor;

/**
 *  设置圆角,默认没有圆角
 */
@property (nonatomic, assign) NSUInteger cornerRadius;

/**
 *  光标宽度,默认为2
 */
@property (nonatomic, assign) NSUInteger cursorWidth;

/**
 *  光标高度,默认为 self.font.lineHeight + 4
 */
@property (nonatomic, assign) NSUInteger cursorHeight;

/**
 *  文字高度改变会自动调用
 *  block参数(text) → 文字内容
 *  block参数(textHeight) → 文字高度
 */
@property (nonatomic, strong) KP_textHeightChangedBlock textChangedBlock;

/**
 *  文字字数超出设定值会自动调用
 *  block参数(maxLengthOfText) → 文字长度最大值
 */
@property (nonatomic, strong) KP_textViewLengthOverLimitBlock textOverLimitBlock;



- (void)textValueDidChanged:(KP_textHeightChangedBlock)block;


- (void)textLengthOverLimit:(KP_textViewLengthOverLimitBlock)block;


@end

.m文件:

//
//  KPTextView.m
//  textViewDemo
//
//  Created by 刘鲲鹏 on 2017/5/12.
//  Copyright © 2017年 刘鲲鹏. All rights reserved.
//

#import "KPTextView.h"

@interface KPTextView ()
{
    UIColor *NormalColor;
}

/**
 *  UILabel作为placeholderView,解决占位符问题.
 */
@property (nonatomic, weak) UILabel *placeholderView;

/**
 *  文字高度
 */
@property (nonatomic, assign) NSInteger textH;

/**
 *  文字最大高度
 */
@property (nonatomic, assign) NSInteger maxTextH;

/**
 *  textView设定的高度
 */
@property (nonatomic, assign) NSInteger textViewSettingHeight;




@end

@implementation KPTextView

- (UILabel *)placeholderView {

    if (!_placeholderView ) {
        UILabel *placeholderView = [[UILabel alloc] init];
        _placeholderView = placeholderView;
        //防止textView输入时跳动问题
//        _placeholderView.scrollEnabled = NO;
//        _placeholderView.showsHorizontalScrollIndicator = NO;
//        _placeholderView.showsVerticalScrollIndicator = NO;
        _placeholderView.userInteractionEnabled = NO;
        _placeholderView.font = self.font;
        _placeholderView.backgroundColor = [UIColor clearColor];
        _placeholderColor = [UIColor lightGrayColor];
        _placeholderView.textColor = _placeholderColor;
        _placeholderView.numberOfLines = 0;
        _maxNumberOfLines = NSIntegerMax;
        [self addSubview:placeholderView];
    }
    return _placeholderView;
}

- (void)setMaxNumberOfLines:(NSUInteger)maxNumberOfLines {
    _maxNumberOfLines = maxNumberOfLines;

    /**
     *  根据最大的行数计算textView的最大高度
     *  计算最大高度 = (每行高度 * 总行数 + 文字上下间距)
     */
    _maxTextH = ceil(self.font.lineHeight * maxNumberOfLines + self.textContainerInset.top + self.textContainerInset.bottom);

}

- (void)setBorderWidth:(NSUInteger)borderWidth {
    _borderWidth = borderWidth;
    self.layer.borderWidth = _borderWidth;
}

- (void)setBorderColor:(UIColor *)borderColor {
    _borderColor = borderColor;
    self.layer.borderColor = _borderColor.CGColor;
}

- (void)setCornerRadius:(NSUInteger)cornerRadius {
    _cornerRadius = cornerRadius;
    self.layer.cornerRadius = cornerRadius;
}

/**
 *  通过设置placeholderColor设置私有属性placeholderView中的textColor
 */
- (void)setPlaceholderColor:(UIColor *)placeholderColor {
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        NormalColor = placeholderColor;
    });
    _placeholderColor = placeholderColor;
    self.placeholderView.textColor = placeholderColor;
}

/**
 *  通过设置placeholder设置私有属性placeholderView中的text
 */
- (void)setPlaceholder:(NSString *)placeholder {
    _placeholder = placeholder;
    self.placeholderView.text = placeholder;
}

/**
 *  通过设置attributedPlaceHolder设置私有属性placeholderView中的attributedText
 */
- (void)setAttributedPlaceHolder:(NSAttributedString *)attributedPlaceHolder {
    _attributedPlaceHolder = attributedPlaceHolder;
    self.placeholderView.attributedText = attributedPlaceHolder;
}

/**
 *  通过设置_placeholderFont设置私有属性placeholderView中的Font
 */
- (void)setPlaceholderFont:(UIFont *)placeholderFont {
    _placeholderFont = placeholderFont;
    self.placeholderView.font = placeholderFont;
    if (self.font && _placeholderFont) {

    }
}

- (void)setFont:(UIFont *)font {
    [super setFont:font];
    self.placeholderView.frame = CGRectMake(7, 8, self.bounds.size.width, font.lineHeight);
}


- (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}

- (void)setup {

    self.scrollEnabled = NO;
    self.scrollsToTop = NO;
    self.showsHorizontalScrollIndicator = NO;
    self.enablesReturnKeyAutomatically = YES;
    self.layer.borderWidth = 1;
    self.layer.borderColor = [UIColor lightGrayColor].CGColor;

    _textViewSettingHeight = self.frame.size.height;
    //实时监听textView值得改变
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBeginEditing) name:UITextViewTextDidBeginEditingNotification object:self];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEndEditing) name:UITextViewTextDidEndEditingNotification object:self];
}

- (void)textDidChange {

    NSInteger wordCount = self.text.length;
//    NSLog(@"%ld",(long)wordCount);
    if (_maxLengthOfText && wordCount >= _maxLengthOfText) {
        self.text = [self.text substringToIndex:_maxLengthOfText];
        if (_textOverLimitBlock) {
            _textOverLimitBlock(_maxLengthOfText);
        }
    }

    // 根据文字内容决定placeholderView是否隐藏
    self.placeholderView.hidden = self.hasText;

    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 && height > _textViewSettingHeight) {
            _textChangedBlock(self.text,height);

            [self.superview layoutIfNeeded];
//            self.placeholderView.frame = self.bounds;
        }


    }
}

- (void)didBeginEditing {
    if (_placeholderHighLightColor) {
        self.placeholderColor = _placeholderHighLightColor;
    }else {
        self.placeholderColor = [UIColor lightGrayColor];
    }
}

- (void)didEndEditing {
    self.placeholderColor = NormalColor;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}



- (void)textValueDidChanged:(KP_textHeightChangedBlock)block {
    _textChangedBlock = block;
}

- (void)textLengthOverLimit:(KP_textViewLengthOverLimitBlock)block {
    _textOverLimitBlock = block;
}


- (CGRect)caretRectForPosition:(UITextPosition *)position
{
    CGRect originalRect = [super caretRectForPosition:position];

    if (_cursorHeight) {
        originalRect.size.height = _cursorHeight;
    }else {
        originalRect.size.height = self.font.lineHeight + 4;
    }
    if (_cursorWidth) {
        originalRect.size.width = _cursorWidth;
    }else {
        originalRect.size.width = 2;
    }

    return originalRect;
}

@end
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值