一行代码实现UITextView的placeHolder

作者: 小小提莫酱 | 来源:发表于2017-06-08 11:59 被阅读1019次
读书无用论的去死.jpg

前言

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

实现效果

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];
调整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"

搭配使用

源码

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

相关文章

网友评论

  • 时光浅影:yytext 貌似有这个
  • Zszen:一行加了buff的代码
  • SLEI:swift 中怎么使用
  • 小小提莫酱:文章末尾添加版本更新记录,跟踪每一次修改问题log。
    时光浅影:@时光浅影 是我的问题
    小小提莫酱:@时光浅影 没有明白你描述的意思...
  • 洁简:这个placeHolder可以距右吗
    小小提莫酱:可以的,placeHolder会跟随UITextView的textAlignment设置。只需要给UItextView设置textAlignment在设置placeHolder之前即可。
  • 布袋的世界:真强大 !楼主要做过上传图片到TextView的Demo吗?
    小小提莫酱:@布袋的世界 图文混排就好了、原理和UILabel的图文混排一致:smile:

本文标题:一行代码实现UITextView的placeHolder

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