UITextField中有一个placeholder属性,可以设置UITextField的占位文字,起到提示用户的作用。可是UITextView就没那么幸运了,apple没有给UITextView提供一个类似于placeholder这样的属性来供开发者使用。下面我就把自己能够想到的和网友提供的方法汇总一下,让更多的开发者知道,原来有这么多方法可以实现UITextView的占位文字。

方法一:

1.把UITextView的text属性当成“placeholder”使用。

2.在开始编辑的代理方法里清除“placeholder”。

3.在结束编辑的代理方法里根据条件设置“placeholder”。

特点:这种方法的特点是,当用户点击了textView,placeholder占位文字就会立马消失,官方的placeholder是当系统监听到用户输入了文字后placeholder才会消失。

// 创建textView
UITextView *textView =[[UITextViewalloc]initWithFrame:CGRectMake(,,SCREEN.width-,)];
textView.backgroundColor= [UIColor whiteColor];
textView.text = @"我是placeholder";
textView.textColor = [UIColor grayColor];
textView.delegate = self;
[self.view addSubview:textView]; #pragma mark - UITextViewDelegate
- (void)textViewDidEndEditing:(UITextView *)textView
{
if(textView.text.length < ){
textView.text = @"我是placeholder";
textView.textColor = [UIColor grayColor];
}
}
- (void)textViewDidBeginEditing:(UITextView *)textView
{
if([textView.text isEqualToString:@"我是placeholder"]){
textView.text=@"";
textView.textColor=[UIColor blackColor];
}
}

方法二:

1.创建textView

2.给textView添加一个UILabel子控件,作为placeholder

3.在文本改变的代理方法里面显示/隐藏UILabel

特点:该方法同样也可以实现类似于placeholder的功能。相比较方法一,方法二可以实现动态监听文本的改变,并非弹出键盘就立即清除placeholder,只有当用户开始输入文本的时候。placeholder才会消失。同样,当用户清空文本的时候,placeholder又会重新显示出来。

同样地思路,我们也可以用两个UITextView来实现placeholder的功能,再次就不在详述。

#import "WSViewController.h"

@interface WSViewController () <UITextViewDelegate>

@property(nonatomic, weak)UITextView *textView;

@property(nonatomic, weak)UILabel *placeHolder;

@end

@implementation WSViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. [self setupTextView]; } // 添加textView
- (void)setupTextView
{
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(, , SCREEN_WIDTH - * , )];
textView.frame = CGRectMake(, , SCREEN_WIDTH - * , ); [self.view addSubview:textView];
self.textView = textView; textView.contentInset = UIEdgeInsetsMake(-, , , ); textView.delegate = self;
[self setupPlaceHolder]; //在弹出的键盘上面加一个view来放置退出键盘的Done按钮
UIToolbar * topView = [[UIToolbar alloc] initWithFrame:CGRectMake(, , , )];
[topView setBarStyle:UIBarStyleDefault];
UIBarButtonItem * btnSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem * doneButton = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(dismissKeyBoard)];
NSArray * buttonsArray = [NSArray arrayWithObjects:btnSpace, doneButton, nil]; [topView setItems:buttonsArray];
[textView setInputAccessoryView:topView]; } // 给textView添加一个UILabel子控件
- (void)setupPlaceHolder
{
UILabel *placeHolder = [[UILabel alloc] initWithFrame:CGRectMake(, -, SCREEN_WIDTH - * , )];
self.placeHolder = placeHolder; placeHolder.text = @"我是placeholder";
placeHolder.textColor = [UIColor lightGrayColor];
placeHolder.numberOfLines = ;
placeHolder.contentMode = UIViewContentModeTop;
[self.textView addSubview:placeHolder];
} #pragma mark - UITextViewDelegate
- (void)textViewDidChange:(UITextView *)textView
{
if (!textView.text.length) {
self.placeHolder.alpha = ;
} else {
self.placeHolder.alpha = ;
}
} //关闭键盘
-(void) dismissKeyBoard{
[self.textView resignFirstResponder];
} @end

方法三:

1.自定义UITextView

2.给UITextView添加placeholder和placeholderColor属性

3.重写initWithFrame方法

4.添加通知监听文字改变

5.重写drawRect:方法

6.重写相关属性的set方法

特点:相比计较上面两种方法,这种方法可移植性、拓展性更好,这种方法,不仅乐意随意通过我们添加的placeholder属性设置默认文字,还可以通过我们添加的placeholderColor设置默认文字的颜色。今后,我们只需要写好这么一个自定义UITextView,就可以一劳永逸。

#import <UIKit/UIKit.h>

@interface WSPlaceholderTextView : UITextView
/** 占位文字 */
@property (nonatomic, copy) NSString *placeholder;
/** 占位文字颜色 */
@property (nonatomic, strong) UIColor *placeholderColor;
@end #import "WSPlaceholderTextView.h" @implementation WSPlaceholderTextView - (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
// 设置默认字体
self.font = [UIFont systemFontOfSize:]; // 设置默认颜色
self.placeholderColor = [UIColor grayColor]; // 使用通知监听文字改变
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:self];
}
return self;
} - (void)textDidChange:(NSNotification *)note
{
// 会重新调用drawRect:方法
[self setNeedsDisplay];
} - (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
} /**
* 每次调用drawRect:方法,都会将以前画的东西清除掉
*/
- (void)drawRect:(CGRect)rect
{
// 如果有文字,就直接返回,不需要画占位文字
if (self.hasText) return; // 属性
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSFontAttributeName] = self.font;
attrs[NSForegroundColorAttributeName] = self.placeholderColor; // 画文字
rect.origin.x = ;
rect.origin.y = ;
rect.size.width -= * rect.origin.x;
[self.placeholder drawInRect:rect withAttributes:attrs];
} - (void)layoutSubviews
{
[super layoutSubviews]; [self setNeedsDisplay];
} #pragma mark - setter
- (void)setPlaceholder:(NSString *)placeholder
{
_placeholder = [placeholder copy]; [self setNeedsDisplay];
} - (void)setPlaceholderColor:(UIColor *)placeholderColor
{
_placeholderColor = placeholderColor; [self setNeedsDisplay];
} - (void)setFont:(UIFont *)font
{
[super setFont:font]; [self setNeedsDisplay];
} - (void)setText:(NSString *)text
{
[super setText:text]; [self setNeedsDisplay];
} - (void)setAttributedText:(NSAttributedString *)attributedText
{
[super setAttributedText:attributedText]; [self setNeedsDisplay];
}
@end

方法四:

1.自定义UITextView

2.给UITextView添加placeholder和placeholderColor属性

3.重写initWithFrame方法

4.重写drawRect:方法

5.重写相关属性的set方法

特点:这个方法的和方法三很相似,只是没有利用通知来监听文本的改变,需要配合textViewDidChanged:这个文本改变的代理方法使用。

#import <UIKit/UIKit.h>

@interface WSTextView : UITextView
/** 占位文字 */
@property (nonatomic,copy) NSString *placeholder;
/** 占位文字颜色 */
@property (nonatomic,strong) UIColor *placeholderColor;
@end #import "WSTextView.h" @implementation WSTextView
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.font = [UIFont systemFontOfSize:];
self.placeholderColor = [UIColor lightGrayColor];
self.placeholder = @"请输入内容";
}
return self;
} // Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSFontAttributeName] = self.font;
attrs[NSForegroundColorAttributeName] = self.placeholderColor; [self.placeholder drawInRect:CGRectMake(, , self.frame.size.width, self.frame.size.height) withAttributes:attrs];
} // 布局子控件的时候需要重绘
- (void)layoutSubviews
{
[super layoutSubviews];
[self setNeedsDisplay]; }
// 设置属性的时候需要重绘,所以需要重写相关属性的set方法
- (void)setPlaceholder:(NSString *)placeholder
{
_placeholder = placeholder;
[self setNeedsDisplay];
} - (void)setPlaceholderColor:(UIColor *)placeholderColor
{
_placeholderColor = placeholderColor;
[self setNeedsDisplay]; } - (void)setFont:(UIFont *)font
{
[super setFont:font];
[self setNeedsDisplay];
} - (void)setText:(NSString *)text
{
[super setText:text];
if (text.length) { // 因为是在文本改变的代理方法中判断是否显示placeholder,而通过代码设置text的方式又不会调用文本改变的代理方法,所以再此根据text是否不为空判断是否显示placeholder。
self.placeholder = @"";
}
[self setNeedsDisplay];
} - (void)setAttributedText:(NSAttributedString *)attributedText
{
[super setAttributedText:attributedText];
if (attributedText.length) {
self.placeholder = @"";
}
[self setNeedsDisplay];
}
@end // 应用的时候需要配合UITextView的文本改变的代理方法 #import "ViewController.h"
#import "WSTextView.h" @interface ViewController ()<UITextViewDelegate> // @property(nonatomic,weak) WSTextView *textView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
WSTextView *textView = [[WSTextView alloc] initWithFrame:CGRectMake(, , self.view.frame.size.width, )];
textView.placeholder = @"ws";
textView.delegate = self;
[self.view addSubview:textView];
// textView.text = @"试试会不会调用文本改变的代理方法"; // 不会调用文本改变的代理方法
textView.attributedText = [[NSAttributedString alloc] initWithString:@"富文本"]; // self.textView = textView;
} #pragma mark - UITextViewDelegate
- (void)textViewDidChange:(WSTextView *)textView // 此处取巧,把代理方法参数类型直接改成自定义的WSTextView类型,为了可以使用自定义的placeholder属性,省去了通过给控制器WSTextView类型属性这样一步。
{
if (textView.hasText) { // textView.text.length
textView.placeholder = @""; } else {
textView.placeholder = @"ws"; }
}
@end

方法五:

通过runtime,我们发现,UITextView内部有一个名为“_placeHolderLabel”的私有成员变量。大家知道,Objective-C没有绝对的私有变量,因为我们可以通过KVC来访问私有变量。

#import "ViewController.h"
#import <objc/runtime.h>
#import <objc/message.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];   // 通过运行时,发现UITextView有一个叫做“_placeHolderLabel”的私有变量
unsigned int count = ;
Ivar *ivars = class_copyIvarList([UITextView class], &count); for (int i = ; i < count; i++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *objcName = [NSString stringWithUTF8String:name];
NSLog(@"%d : %@",i,objcName);
} [self setupTextView]; }
- (void)setupTextView
{
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(, , [UIScreen mainScreen].bounds.size.width, 100];
[textView setBackgroundColor:[UIColor greenColor]];
[self.view addSubview:textView]; // _placeholderLabel
UILabel *placeHolderLabel = [[UILabel alloc] init];
placeHolderLabel.text = @"请输入内容";
placeHolderLabel.numberOfLines = ;
placeHolderLabel.textColor = [UIColor lightGrayColor];
[placeHolderLabel sizeToFit];
[textView addSubview:placeHolderLabel]; [textView setValue:placeHolderLabel forKey:@"_placeholderLabel"]; } @end

UITextView实现placeHolder方法汇总的更多相关文章

  1. UITextView 实现placeholder的方法

    本文转载至 http://www.cnblogs.com/easonoutlook/archive/2012/12/28/2837665.html 在UITextField中自带placeholder ...

  2. iOS - UITextView实现placeHolder占位文字

      iOS之UITextView实现placeHolder占位文字的N种方法 前言 iOS开发中,UITextField和UITextView是最常用的文本接受类和文本展示类的控件.UITextFie ...

  3. 教大家怎样给UITextView加入placeholder扩展

    怎样扩展UITextView以追加placeholder功能呢? 我们的需求是:追加placeholder功能 方案讨论: 通过继承UITextView的方式 通过扩展UITextView的方式 分析 ...

  4. UITextView实现PlaceHolder的方式

    实现UITextView实现PlaceHolder的方式的方式有两种,这两种方法的核心就是通过通知来添加和去除PlaceHolder:下面来介绍两种方法:个人比较喜欢第一种,看起来更加合理. 方法1: ...

  5. 你真的会玩SQL吗?实用函数方法汇总

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  6. Java实现时间动态显示方法汇总

    这篇文章主要介绍了Java实现时间动态显示方法汇总,很实用的功能,需要的朋友可以参考下 本文所述实例可以实现Java在界面上动态的显示时间.具体实现方法汇总如下: 1.方法一 用TimerTask: ...

  7. C#读写文件的方法汇总_C#教程_脚本之家

    C#读写文件的方法汇总_C#教程_脚本之家 http://www.jb51.net/article/34936.htm

  8. 将编码从GB2312转成UTF-8的方法汇总(从前台、程序、数据库)

    这篇文章主要介绍了将编码从GB2312转成UTF-8的方法汇总(从前台.程序.数据库),需要的朋友可以参考下 一个网站如果需要国际化,就需要将编码从GB2312转成UTF-8,其中有很多的问题需要注意 ...

  9. 本地获取System权限CMD方法汇总(转)

    本地获取System权限CMD方法汇总(转) 稍微整理了下,大概有三种方法可以本地获取system权限的cmd,但前提都是当前用户具备administrator权限. 下面列举的三种方法各有千秋,看你 ...

随机推荐

  1. java 23 - 1 设计模式之工厂方法模式

    转载: JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

  2. https证书提供商

    http://www.itrus.com.cn/verisignchina/About/aboutitrus/Index.html

  3. iOS NSFileManager 使用详解

    使用NSFileManager 文件系统接口 允许访问文件夹内容 创建 重命名 删除文件 修改文件和文件属性,以及Finder对所有文件系统任务执行的一般操作. 访问NSFileManager,使用共 ...

  4. windows和ubuntu下gif动态图片的制作

    现在社交软件中, 各种各样的动图为大家交流很大的乐趣.  Gif图片比视频小, 比静态JPG图片形象生动, 更适用于产品展示和步骤演示等. 这里简单介绍一下在window系统和ubuntu系统下gif ...

  5. Splay整理

    伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.(来自百科) 伸展树的操作主要是

  6. Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...

  7. 条件变量pthread_cond_t怎么用

    #include <pthread.h> #include <stdio.h> #include <stdlib.h> pthread_mutex_t mutex ...

  8. Linux 网络编程详解一(IP套接字结构体、网络字节序,地址转换函数)

    IPv4套接字地址结构 struct sockaddr_in { uint8_t sinlen;(4个字节) sa_family_t sin_family;(4个字节) in_port_t sin_p ...

  9. 毫米转换为PX

    公式:毫米数/25.4*你的电脑的DPI,win7 DPI  100%缩放为96,125%为120,150%为144,200%为192 象素数 / DPI = 英寸数 英寸数 * 25.4 = 毫米数

  10. Android -- TouchDelegate

    设计规定 Android4.0设计规定的有效可触摸的UI元素标准是48dp,这是一个用户手指能准确并且舒适触摸的区域. 如下图所示,你的UI元素可能小于48dp,图标仅有32dp,按钮仅有40dp,但 ...