iOS 上自带的UITextView竟然不能设置placeholder,但是UITextView却可以,我也真是醉了。没办法了,自己写一个

DJTextView.h

#import <UIKit/UIKit.h>

@interface DJTextView : UITextView

@property (nonatomic,copy) NSString *placeholder;
@property (nonatomic,strong) UIColor *placeholderColor; @end

DJTextView.m

#import "DJTextView.h"

@implementation DJTextView

- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 在通知中心为TextView注册一个当文本改变的通知,当文本发生变化时,TextView会发一个通知
// 类似于android里面的BroadcastReceiver
// iOS 注册接收通知的方式为:addObserver name:
// android 注册接收通知的方式为:intent.addAction();
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textHasChange) name:UITextViewTextDidChangeNotification object:self];
}
return self;
} // 当文字改变时会调用此方法
- (void)textHasChange { // setNeedsDisplay 类似于android里面的postInvalidate()方法,都是向操作系统发出请求重绘的消息
// 操作系统会在未来的时间内调用drawRect(iOS),onDraw(android);
// 注意:系统不允许我们自己调用drawRect或onDraw方法
[self setNeedsDisplay]; } - (void)drawRect:(CGRect)rect { if ([self hasText]) return; // 如果检测到当前TextView中有文本,就不再绘制 CGFloat placeholderRectX = ;
CGFloat placeholderRectY = ;
CGFloat placeholderRectW = rect.size.width - * placeholderRectX;
CGFloat placeholderRectH = rect.size.height - * placeholderRectY; // 将文本绘制在一个指定的矩形框内
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSFontAttributeName] = self.font;
// 若用户没有设置placeholder的颜色,则给placeholder设置一个默认颜色
attrs[NSForegroundColorAttributeName] = self.placeholderColor ? self.placeholderColor : [UIColor grayColor];
[self.placeholder drawInRect:CGRectMake(placeholderRectX, placeholderRectY, placeholderRectW, placeholderRectH) withAttributes:attrs]; } #pragma mark - 当用户手动更新当前字体属性时,就自动触发重绘
- (void)setText:(NSString *)text{ [super setText:text];
[self setNeedsDisplay]; } - (void)setFont:(UIFont *)font { [super setFont:font];
[self setNeedsDisplay]; } - (void)setPlaceholder:(NSString *)placeholder { _placeholder = placeholder;
[self setNeedsDisplay]; } - (void)setPlaceholderColor:(UIColor *)placeholderColor { _placeholderColor = placeholderColor;
[self setNeedsDisplay]; } - (void)dealloc { // 类似于android,通知中心在使用完毕后需要销毁
// iOS: [NSNotificationCenter defaultCenter] removeObserver:self]
// android: unRegister(mBroadcastReceiver);
[[NSNotificationCenter defaultCenter] removeObserver:self]; } @end

最终效果:

新浪微博客户端(36)-自定义带placeholder的TextView的更多相关文章

  1. 李洪强iOS开发之带placeHolder的Textview

    李洪强iOS开发之带placeHolder的Textview  01 - 创建工过程,定义全局属性,遵守textview的代理协议  02 - 添加一个textview和一个label 03 - 实现 ...

  2. 新浪微博客户端(5)-自定义UISearchBar

    iOS自带的UISearchBar有很多限制,我们可以使用UITextField做出一个类似于SearchBar的效果. //===================================== ...

  3. 新浪微博客户端(2)-自定义导航控制器,统一NavigationItem

      继承系统提供的UINavigationViewController,拦截并重写其push方法. #import "DJNavigationController.h" @impl ...

  4. 新浪微博客户端(11)-自定义checkBox

    在最后一个欢迎界面上添加一个CheckBox. // 2.添加4个UIImageView ; i < NEW_FEATURE_NUMS; i++) { UIImageView *imageVie ...

  5. Android自定义控件 -- 带边框的TextView

    使用xml实现边框 原来使用带边框的TextView时一般都是用XML定义来完成,在drawable目录中定义如下所示的xml文件: <?xml version="1.0" ...

  6. android开发新浪微博客户端 完整攻略 [新手必读]

    开始接触学习android已经有3个礼拜了,一直都是对着android的sdk文档写Tutorials从Hello World到Notepad Tutorial算是初步入门了吧,刚好最近对微博感兴趣就 ...

  7. Android实现自定义带文字和图片的Button

    Android实现自定义带文字和图片的Button 在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法. 一.用系统自带的Button实现 最简单的一种办法就 ...

  8. 自定义带图片和文字的ImageTextButton

    今天我们来讲一下有关自定义控件的问题,今天讲的这篇是从布局自定义开始的,难度不大,一看就明白,估计有的同学或者开发者看了说,这种方式多此一举,但是小编我不这么认为,多一种解决方式,就多一种举一反三的学 ...

  9. Android应用--新浪微博客户端新特性滚动视图和启动界面实现

    新浪微博客户端新特性滚动视图和启动界面实现 2013年8月20日新浪微博客户端开发之启动界面实现 前言: 使用过新浪微博客户端的童鞋都清楚,客户端每一次升级之后第一次启动界面就会有新特性的介绍,用户通 ...

随机推荐

  1. Leetcode House Robber II

    本题和House Robber差不多,分成两种情况来解决.第一家是不是偷了,如果偷了,那么最后一家肯定不能偷. class Solution(object): def rob(self, nums): ...

  2. 【BZOJ-1060】时态同步 树形DP (DFS爆搜)

    1060: [ZJOI2007]时态同步 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2101  Solved: 595[Submit][Statu ...

  3. 【BZOJ-1500】维修数列 Splay

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 11047  Solved: 3460[Submit][Statu ...

  4. 虚拟机克隆后找不到eth0

    使用 VMware 虚拟机的克隆功能,快速复制已安装好的 Linux 系统. 克隆完成之后,发现没有 eth0 网卡. [解决方法] 1. 编辑 /etc/udev/rules.d/70-persis ...

  5. 为什么要用hibernate 与基于数据库表结构的项目开发

    最近开始学习hibernate,其实并不知道要学习什么,有什么用.后来问了一下同事,他就说快捷方便简单,很多事情不用自己做他会帮你做好,但是我觉得不应该是这样的,于是我就去搜了一下,就搜到了一篇帖子, ...

  6. Shell变量的定义与赋值操作注意事项

    1 shell变量是弱类型 * 声明变量不用声明类型 * 可以存储不同类型的内容 * 使用时要明确变量的类型 * 区分大小写 2 变量声明及赋值格式 2.1 格式  变量名=变量值 # 注意等号两侧不 ...

  7. 洛谷P1901 发射站

    题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接 ...

  8. C#制作验证码

    void CodeImage(string code) { if (code == null || code.Trim() == string.Empty) return; System.Drawin ...

  9. EF-CodeFirst 继承关系TPH、TPT、TPC

    继承关系 面向对象的三大特征之一:继承 ,在开发中起到了重要的作用.我们的实体本身也是类,继承自然是没有问题.下面开始分析 EF里的继承映射关系TPH.TPT.TPC 现在我们有这样一个需求,用户里要 ...

  10. C++ essentials 之 union

    Extraction from The C++ Programming Language 4th. edition, Bjarne Stroustrup [8.1] A struct is a seq ...