#import "YGTextView.h"

#define kPlaceholderDefaultTopMargin 4     // Placeholder上下间距
#define kPlaceholderDefaultLeftMargin 5    // Placeholder左右间距
@implementation YGTextView

#pragma mark - 初始化PlaceholderTextView
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    
    if (self)
    {
        self.opaque = YES;
        
        // 设置通知, 当TextView文字发生改变时, 向自己发送通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChanged) name:UITextViewTextDidChangeNotification object:self];
    }
    
    return self;
}

#pragma mark - 通知事件
- (void)textDidChanged
{
    // 重新绘制
    [self setNeedsDisplay];
}

#pragma mark - 重写属性方法, 实时绘制
- (void)setPlaceholder:(NSString *)placeholder
{
    _placeholder = [placeholder copy];
    
    [self setNeedsDisplay];
}

- (void)setPlaceholderColor:(UIColor *)placeholderColor
{
    _placeholderColor = placeholderColor;
    
    [self setNeedsDisplay];
}

- (void)setText:(NSString *)text
{
    [super setText:text]; // 系统自带属性
    
    [self setNeedsDisplay];
}

- (void)setAttributedText:(NSAttributedString *)attributedText
{
    [super setAttributedText:attributedText];
    
    [self setNeedsDisplay];
}

- (void)setFont:(UIFont *)font
{
    [super setFont:font];
    
    // 会在下一个消息循环调用drawRect
    [self setNeedsDisplay];
}

#pragma mark - 绘制子控件
- (void)drawRect:(CGRect)rect
{
    // 若TextView有文字
    if (self.hasText)
    {
        return;
    }
    
    // 文字属性
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    attrs[NSFontAttributeName] = self.font; // 获取当前PlaceholderTextView的文字属性
    attrs[NSForegroundColorAttributeName] = self.placeholderColor ? self.placeholderColor : [UIColor lightGrayColor];
    
    // 绘制范围
    CGFloat placeholderTopMargin = self.placeholderTopMargin ? self.placeholderTopMargin : kPlaceholderDefaultTopMargin;
    CGFloat placeholderLeftMargin = self.placeholderLeftMargin ? self.placeholderLeftMargin : kPlaceholderDefaultTopMargin;
    
    CGFloat placeholderX = placeholderTopMargin;
    CGFloat placeholderY = placeholderLeftMargin;
    CGFloat placeholderW = rect.size.width - 2 * placeholderLeftMargin;
    CGFloat placeholderH = rect.size.height - 2 * placeholderTopMargin;
    CGRect placeholderRect = CGRectMake(placeholderX, placeholderY, placeholderW, placeholderH);
    
    [self.placeholder drawInRect:placeholderRect withAttributes:attrs];
}

#pragma mark - 移除通知
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end

UITextView添加占位字符相关推荐

  1. 文本视图(UITextView)占位符Swift

    本文翻译自:Text View (UITextView) Placeholder Swift I'm making an application which uses a UITextView . 我 ...

  2. 字符串处理 —— 回文串相关 —— 添加/删除字符后是否为回文串

    [问题] 给定一个字符串,问对该字符串,是否能通过添加一个字符后变为回文串. 若可以,输出 YES,否则输出 NO 对于该问题,首先要明白,删除一个字符与添加一个字符在判断回文串中是等价的. [暴力枚 ...

  3. ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器。用springframework自带的便可...

    ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器.用springframework自带的便可 转载于:https://www.cnblogs.com/oymx/p/3976392. ...

  4. notepad++添加HEX插件,编辑歌曲ID3信息,UTF8,UTF16 encoded Unicode,添加U2020字符方法

    介绍 notepad++的插件HEX,可编辑歌曲的ID3 tag信息,包括Album.Artist.Track信息. 现象 信息歌曲的ID3信息时,受操作系统影响.最好使用notepad++,直接编辑 ...

  5. 为 contenteditable 元素添加占位符

    假设我们想要为具有给定 contenteditable 属性的元素设置一个占位符: <div contenteditable></div> 注意:contenteditable ...

  6. c语言 字符串数组末尾,C语言中,利用宏定义一个字符串和字符数组定义的字符串其末尾都会自动添加\0字符...

    利用宏定义一个字符串#define MYPHONE "AT+CMGS" 字符数组的方式来定义一个字符串unsigned char SMS[]="HELLO, WELCOM ...

  7. char添加一个字符_C语言动态接收多个字符串

    1. 背景与基本原理      在一些场合下,用户往往需要动态输入字符串,如果程序能够自动接收传进的字符串并进行计数,便可以达到动态接收的效果.基本原理是定义一个指向字符串指针的指针,对其进行进一步细 ...

  8. char添加一个字符_给你五十行代码把图片变成字符画!程序:太多了,一半都用不完...

    今天和大家分享一个简单又好玩的Python项目–"图片转字符画".废话不多说,先上一个效果图迷惑一下众生. 没错的,图片转字符画就是将我们平常所看到的的图片根据像素RGB值和灰度值 ...

  9. char添加一个字符_LINUX字符设备驱动模型分析(起始篇)

    在前面几个模块的介绍中,我们主要以vfs为起始,完成了sysfs.设备-总线-驱动模型.platform设备驱动模型.i2c设备驱动模型.spi设备驱动模型的分析.在对这些模块进行分析的时候,我们或多 ...

最新文章

  1. 06上半年网络工程师试题分类精讲.第一部分:计算机与网络知识(上午考试科目).第一章:计算机系统知识...
  2. OpenTelemetry 简析
  3. Samba服务器的安装配置【十全十美】
  4. 免费wordpress主题在线生成网站
  5. 浅显易懂的GMM模型及其训练过程
  6. 【转】JS判断SWF,JPG加载完毕、兼容(Activex,plugIn)所有浏览器
  7. 淺談auto_ptr
  8. Codeforces Round #296 (Div. 1) E. Triangles 3000
  9. python入门教程傻瓜版_大数据学习资料集--2014-12-23
  10. 关于DNF的多媒体包NPK文件的那些事儿(1)
  11. SQL注入不完全思路与防注入程序
  12. 为何Set检索效率低下
  13. python绘图之Times New Roman字体以及Helvetica字体
  14. web爬虫讲解—urllib库中使用xpath表达式—BeautifulSoup基础
  15. 解密新晋信息窃取木马Spymel
  16. nisp一级练习题及答案
  17. 统计每天的新老用户,日活,周活,月活
  18. 实现Android跨进程组件通信能有多简单?
  19. 内网渗透:二、内网渗透的信息收集
  20. ORACLE数据库 AWR报告收集

热门文章

  1. Spring学习-理解IOC和依赖注入
  2. 有关C/C++中,表达式计算顺序的问题,以及表达式内部变量“副作用”问题(转)...
  3. JAVA面试题(2)
  4. Python如何进行cross validation training
  5. hdu 2087 剪花布条
  6. 全面认识一下.NET 4.0的缓存功能
  7. [翻译]ASP.NET MVC 3 开发的20个秘诀(十二)[20 Recipes for Programming MVC 3]:缩放图片尺寸创建缩略图...
  8. CreateFileMapping
  9. CentOS下安装NetBeans集成开发环境
  10. TCP/IP四层模型和OSI七层模型