高度自定义TextView 绝对满足你

我们知道iOS自带的UITextView基本很难满足我们的日常使用。我项目中textView是继承与UITextview的,自定义了一个TextView,主要实现的以下功能。

  1. 添加placeHolder
  2. 高度自适应
  3. 可以设置行间距
  4. 支持xib

其实实现起来也是很简单,但是非常的实用。
一. 先看一下头文件
@interface STTextView : UITextView
/** 占位文字 */
@property (nonatomic, copy) NSString *placeholder;
/** 占位文字颜色 */
@property (nonatomic, strong) UIColor *placeholderColor;
//行间距 
@property (nonatomic, assign) CGFloat verticalSpacing;
/**设置最大高度*/
@property (nonatomic, assign) CGFloat maxHeight;
/**设置最小高度*/
@property (nonatomic, assign) CGFloat minHeight;
/**是不是自适应高度,默认为YES*/
@property (nonatomic, assign) BOOL isAutoHeight;
@property (nonatomic, copy) void(^textDidChangedBlock)(NSString * text);
@property (nonatomic, copy) void (^textViewAutoHeight)(CGFloat textHeight);
@end

应该是一目了然的吧。

二. 看一下实现过程
  1. 这里我是用的是一个UILabel来充当占位符,控制其隐藏和显示达到效果。其实还可以通过重写draw方法,进行绘制placeHolder。这里考虑到实际使用过程中,会出现占位符很长,出现换行的情况,使用一个Label可能会更加方便,如下图这种情况:

高度自定义TextView 绝对满足你_第1张图片

2.占位Label的坐标其实还是很讲究的
我们知道默认的UITextView会有一个默认的边距为textContainerInset =UIEdgeInsetsMake (8, 0, 8, 0),所以设置placeHolder坐标应该考虑到这一点,否则像我这种有点强迫症的人看着很不舒服。我解决方案是添加@property (nonatomic, assign) UIEdgeInsets placeHolderLabelInsets;属性,重写textContainerInset属性,代码如下:

#pragma mark ---setter
- (void)setTextContainerInset:(UIEdgeInsets)textContainerInset{
    //调整text内容边距
    [super setTextContainerInset:textContainerInset];
    self.placeHolderLabelInsets = UIEdgeInsetsMake(textContainerInset.top, textContainerInset.left + 2, textContainerInset.bottom, textContainerInset.right + 2);
    [self setNeedsLayout];
}

这样我们就可以自由设置文字边距,而不用再特意去调整placeHoler的坐标了,看一下实际效果图:
1. tv.textContainerInset = UIEdgeInsetsZero
高度自定义TextView 绝对满足你_第2张图片
2. textContainerInset默认值
高度自定义TextView 绝对满足你_第3张图片
3. 设置间距tv.textContainerInset = UIEdgeInsetsMake(15, 10, 15, 10);
高度自定义TextView 绝对满足你_第4张图片
这样使用起来就简单多了吧。
3.有一点需要注意的是 使用系统默认键盘时候,应处理一下待选字体,否则会出现输入时候自动把待选字体带进输入框,体验很差,因为待选文字时候也会进入监听方法,这时候我们需要判断有没有待选文字,

if(self.markedTextRange == nil){
        //没有候选字符
        [self st_setAttributedString];
        self.textDidChangedBlock ? self.textDidChangedBlock(self.text) : nil;
    };

self.markedTextRange == nil 进行处理即可
4.当设置行间距的删除文字的时候,我们应该保持光标位置,否则用户删除中间字体的时候,会不断跳到最后边,如下图:
高度自定义TextView 绝对满足你_第5张图片
解决这个问题很简单 只需要 记录一下光标位置,重新设置一下即可

NSRange range = self.selectedRange;
self.attributedText = [[NSAttributedString alloc]initWithString:self.text attributes:[self attrs]];
 self.selectedRange = range;

如下图:
高度自定义TextView 绝对满足你_第6张图片
基本上这都是实际使用中需要注意到的问题,其实代码什么的都挺简单。

看一下实际使用效果吧:

希望能够帮助到大家吧,demo已上传到我的github,下载拖进工程即可使用,如果使用中有什么问题请及时与我联系。

你可能感兴趣的:(高度自定义TextView 绝对满足你)