一行代码实现UITextView的placeHolder

一行代码实现UITextView的placeHolder_第1张图片
读书无用论的去死.jpg

前言

通过Category一行代码实现UITextView的placeHolder。搭配使用一行代码限制并统计UITextView输入字数效果更佳。

实现效果

一行代码实现UITextView的placeHolder_第2张图片
ZWPlaceHolder+LimitCouner.gif

导入头文件

#import "UITextView+ZWPlaceHolder.h"
  • storyboard(xib)一行调用代码
self.firstTextView.zw_placeHolder = @"向厂家反馈同业相关活动、产品信息、用于市场分析。";
  • 代码创建UITextView调用
    CGRect rect = CGRectMake(5, 230, [UIScreen mainScreen].bounds.size.width-10, 80);
    UITextView *textView = [[UITextView alloc] initWithFrame:rect];
    textView.layer.borderWidth = 1;
    textView.font = [UIFont systemFontOfSize:14];
    textView.layer.borderColor = [UIColor lightGrayColor].CGColor;
    textView.zw_placeHolder = @"向厂家反馈同业相关活动、产品信息、用于市场分析。";
    [self.view addSubview:textView];
  • 调整placeHolder的字体大小
    • placeholder的字体大小会跟随UITextView字体大小而变化,可以通过调整UITextView的font来调整PlaceHolder字体大小
textView.font = [UIFont systemFontOfSize:14];
  • 调整placeHolder的字体颜色
textView.zw_placeHolderColor = [UIColor redColor];
一行代码实现UITextView的placeHolder_第3张图片
调整placeHolder字体颜色.png

实现源码解析

  • 在UITextView的category中通过runtime添加属性zw_placeHolder,当给zw_placeHolder赋值时,去创建一个UILabel添加到UITextView上,然后监听UITextView中text的改变来选择是否显示placeHolder。
  • 核心代码
#pragma mark - update
- (void)updatePlaceHolder{
    if (self.text.length) {
        [self.zw_placeHolderLabel removeFromSuperview];
        return;
    }
    self.zw_placeHolderLabel.font = self.font?self.font:self.cacutDefaultFont;
    self.zw_placeHolderLabel.textAlignment = self.textAlignment;
    self.zw_placeHolderLabel.text = self.zw_placeHolder;
    [self insertSubview:self.zw_placeHolderLabel atIndex:0];
}
#pragma mark - lazzing
-(UILabel *)zw_placeHolderLabel{
    UILabel *placeHolderLab = objc_getAssociatedObject(self, @selector(zw_placeHolderLabel));
    if (!placeHolderLab) {
        placeHolderLab = [[UILabel alloc] init];
        placeHolderLab.numberOfLines = 0;
        placeHolderLab.textColor = [UIColor lightGrayColor];
        objc_setAssociatedObject(self, @selector(zw_placeHolderLabel), placeHolderLab, OBJC_ASSOCIATION_RETAIN);
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePlaceHolder) name:UITextViewTextDidChangeNotification object:self];
    }
    return placeHolderLab;
}
  • 如何避免placeHolder被光标遮挡。
    UITextView的光标默认边距是5.0。
// Default value: 5.0  The layout padding at the beginning and end of the line fragment rects insetting the layout width available for the contents.  This value is utilized by NSLayoutManager for determining the layout width.
@property(NS_NONATOMIC_IOSONLY) CGFloat lineFragmentPadding;
  • 所以计算自定义placeHolder的位置需要加上这个边距
  • 关于UITextView的textContainerInset导致文字偏移
  • UITextView可以通过设置textContainerInset来让文字输入区域偏移。
CGFloat x = lineFragmentPadding + textContainerInset.left + self.layer.borderWidth;

placeHolder的x坐标 = 光标偏移量+text偏移量+border边框宽度。
其他坐标同理算得。

如何使用

  • cocoapods导入(搜索不到请更新本地仓库)
pod   'ZWPlaceHolder'
  • 直接将文件拖入工程中,引入头文件即可
#import "UITextView+ZWPlaceHolder.h"

搭配使用

  • 参考上一篇一行代码限制并统计UITextView输入字数
    一行代码实现UITextView的placeHolder_第4张图片
    搭配.gif

源码

  • 源码放在GitHub上,欢迎指正,记得star哦!
cocoapod版本更新记录
  • 0.0.2 ---2017-09-14
    • 修改当设置placeHolder后给UITextView的Text赋值,导致文字覆盖在placeHolder上的bug.
    • 添加和UITextField统一的placeholder属性、为部分第三方键盘框架提供支持。例如:IQKeyboardManager会读取placeholder属性并创建UIToolbar.

你可能感兴趣的:(一行代码实现UITextView的placeHolder)