UITextField 有个系统自带的文本提示文字也就是placeholder属性,大家应该都知道,最常见的就用在搜索框上面的提醒文字。但是UITextField因为只能输入一行文字的原因,可能有时候不能满足我们的需求,这时候 UITextView 这个控件就派到用场了。但是UITextView虽然支持输入多行文字,却没有像 UITextField那样有个placeholder属性给我们调用,本文就是教大家如何给 UITextView 增加一个 placeholder属性。废话不多少,我们开始:
虽然这个号早就不维护了,但是好多人有问题,所有又跑上来更新下!
时光飞逝啊,当初写下这篇文章的日子是 `2015.05.24 11:50`,想想现在自己还在 iOS 开发这条路上辛苦的爬着,废话不多说,有兴趣的去看看下面这个地址的 demo 吧:
https://github.com/ifelseboyxx/XXTextView
UITextField 有个系统自带的文本提示文字也就是placeholder属性,大家应该都知道,最常见的就用在搜索框上面的提醒文字。但是UITextField因为只能输入一行文字的原因,可能有时候不能满足我们的需求,这时候 UITextView 这个控件就派到用场了。但是UITextView虽然支持输入多行文字,却没有像 UITextField那样有个placeholder属性给我们调用,本文就是教大家如何给 UITextView 增加一个 placeholder属性。废话不多少,我们开始:
(一)我们先新建一个继承自 UITextView 的 自定义控件 JSTextView。
(二) 然后在 - (instancetype)initWithFrame:(CGRect)frame 的里面初始化一个 UILabel。没错,我的思路就是用一个 UILabel 来实现 placeholder 效果。具体代码如下:
JSTextView.h 文件
这里我们暴露出 一个文字和文字颜色属性,能够方便我们使用的时候设置这些属性!
#import <UIKit/UIKit.h>
@interface JSTextView :UITextView
@property(nonatomic,copy) NSString *myPlaceholder; //文字
@property(nonatomic,strong) UIColor *myPlaceholderColor; //文字颜色
@end
JSTextView.m 文件
#import"JSTextView.h"
@interface JSTextView()
@property (nonatomic,weak) UILabel *placeholderLabel; //这里先拿出这个label以方便我们后面的使用
@end
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if(self) {
self.backgroundColor= [UIColor clearColor];
UILabel *placeholderLabel = [[UILabel alloc]init];//添加一个占位label
placeholderLabel.backgroundColor= [UIColor clearColor];
placeholderLabel.numberOfLines=0; //设置可以输入多行文字时可以自动换行
[self addSubview:placeholderLabel];
self.placeholderLabel= placeholderLabel; //赋值保存
self.myPlaceholderColor= [UIColor lightGrayColor]; //设置占位文字默认颜色
self.font= [UIFont systemFontOfSize:15]; //设置默认的字体
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self]; //通知:监听文字的改变
}
return self;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self]; //通知:监听文字的改变
这里我来解释下: 这个UITextViewTextDidChangeNotification通知会监听UITextView文字的改变,也就是说只要文字一改变就会调用这个通知的方法,利用这个我们可以控制 我们刚才在- (instancetype)initWithFrame:(CGRect)frame 方法里面初始化的 UILabel 的显示和隐藏:
#pragma mark -监听文字改变
- (void)textDidChange {
self.placeholderLabel.hidden = self.hasText;
}
注:这个 hasText 是一个 系统的 BOOL 属性,如果 UITextView 输入了文字 hasText 就是 YES,反之就为 NO。
(三)我们在 - (void)layoutSubviews 方法里面设置 UILabel 的 frame.
- (void)layoutSubviews {
[super layoutSubviews];
self.placeholderLabel.y=8; //设置UILabel 的 y值
self.placeholderLabel.x=5;//设置 UILabel 的 x 值
self.placeholderLabel.width=self.width-self.placeholderLabel.x*2.0; //设置 UILabel 的 x
//根据文字计算高度
CGSize maxSize =CGSizeMake(self.placeholderLabel.width,MAXFLOAT);
self.placeholderLabel.height= [self.myPlaceholder boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.placeholderLabel.font} context:nil].size.height;
}
注:- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary*)attributes context:(NSStringDrawingContext*)contextNS_AVAILABLE_IOS(7_0); 这个方法我来解释下:
以前我们想要获得 UILabel 文字的大小都用的下图的一系列接口:
但是 这些方法已经被苹果遗弃了,并且出现了新的方法,也就是上面的那个方法。
图1(1)size参数: 宽高限制,用于计算文本绘制时占据的矩形块 。
(2)options参数: NSStringDrawingOptions 大家可以看看这个 官方介绍。在多行的情况下 至少要包含 NSStringDrawingUsesLineFragmentOrigin NSStringDrawingUsesFontLeading 这两个属性。
(3) attributes参数: 这是个字典 @{NSFontAttributeName : self.placeholderLabel.font} 这里注意要成对的传。
(4)context参数 : 可以为 nil 。
(四) 重写我们 暴露出来的 文字 ,颜色以及系统的font 的 set方法 :
- (void)setMyPlaceholder:(NSString*)myPlaceholder{
_myPlaceholder= [myPlaceholder copy];
//设置文字
self.placeholderLabel.text= myPlaceholder;
//重新计算子控件frame
[self setNeedsLayout];
}
- (void)setMyPlaceholderColor:(UIColor*)myPlaceholderColor{
_myPlaceholderColor= myPlaceholderColor;
//设置颜色
self.placeholderLabel.textColor= myPlaceholderColor;
}
//重写这个set方法保持font一致
- (void)setFont:(UIFont*)font {
[super setFont:font];
self.placeholderLabel.font= font;
//重新计算子控件frame
[self setNeedsLayout];
}
(五) 重写 - (void)setText:(NSString*)text 以及 - (void)setAttributedText:(NSAttributedString*)attributedText 方法来控制 UILabel 的显示 和 隐藏
- (void)setText:(NSString*)text{
[super setText:text];
[self textDidChange]; //这里调用的就是 UITextViewTextDidChangeNotification 通知的回调
}
- (void)setAttributedText:(NSAttributedString*)attributedText {
[super setAttributedText:attributedText];
[self textDidChange]; //这里调用的就是UITextViewTextDidChangeNotification 通知的回调
}
(六) 最后别忘了销毁 通知
- (void)dealloc{
[[NSNotificationCenter defaultCenter]removeObserver:UITextViewTextDidChangeNotification];
}
(7) 如何使用
- (void)setUpTextView {
JSTextView *textView = [[JSTextView alloc]initWithFrame:self.view.bounds];
[self.view addSubview:textView];
//1.设置提醒文字
textView.myPlaceholder=@"分享新鲜事...";
//2.设置提醒文字颜色
textView.myPlaceholderColor= [UIColorlightGrayColor];
网友评论
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshPlaceholder) name:UITextViewTextDidChangeNotification object:self];
不过分享我的一个方法。
直接给textView 加一个子label,然后根据textView的内容>0隐藏lab,else 显示lab