实现UITextView实现PlaceHolder的方式的方式有两种,这两种方法的核心就是通过通知来添加和去除PlaceHolder;下面来介绍两种方法;个人比较喜欢第一种,看起来更加合理。
方法1:原理是通过通知来改变PlaceHolder,把PlaceHolder看成是一个UILabel,设置UILabel的透明度,来让Placeholder显示与不显示。这种方法对UITextView本身影响较小。学习自Fly_Elephant:《UITextView实现PlaceHolder的方式》这篇文章
.h文件
#import <UIKit/UIKit.h> @interface DLTextView : UITextView @property (nonatomic, retain) NSString *placeholder; @property (nonatomic, retain) UIColor *placeholderColor; - (void)textChanged:(NSNotification*)notification; @end
.m文件
#import "DLTextView.h" @interface DLTextView () @property (nonatomic, retain) UILabel *placeHolderLabel; @end @implementation DLTextView CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25; - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)awakeFromNib { [super awakeFromNib]; if (!self.placeholder) { [self setPlaceholder:@""]; } if (!self.placeholderColor) { [self setPlaceholderColor:[UIColor lightGrayColor]]; } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; } - (id)initWithFrame:(CGRect)frame { if( (self = [super initWithFrame:frame]) ) { [self setPlaceholder:@""]; [self setPlaceholderColor:[UIColor lightGrayColor]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; } return self; } - (void)textChanged:(NSNotification *)notification { if([[self placeholder] length] == 0) { return; } [UIView animateWithDuration:UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION animations:^{ if([[self text] length] == 0) { [[self viewWithTag:999] setAlpha:1]; } else { [[self viewWithTag:999] setAlpha:0]; } }]; } - (void)setText:(NSString *)text { [super setText:text]; [self textChanged:nil]; } - (void)drawRect:(CGRect)rect { if( [[self placeholder] length] > 0 ) { if (_placeHolderLabel == nil ) { _placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(8, 8, self.bounds.size.width, 10)]; _placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping; _placeHolderLabel.numberOfLines = 0; // _placeHolderLabel.font = self.font; _placeHolderLabel.font = [UIFont systemFontOfSize:13.0]; _placeHolderLabel.backgroundColor = [UIColor clearColor]; _placeHolderLabel.textColor = self.placeholderColor; _placeHolderLabel.alpha = 0; _placeHolderLabel.tag = 999; [self addSubview:_placeHolderLabel]; } _placeHolderLabel.text = self.placeholder; [_placeHolderLabel sizeToFit]; [self sendSubviewToBack:_placeHolderLabel]; } if( [[self text] length] == 0 && [[self placeholder] length] > 0 ) { [[self viewWithTag:999] setAlpha:1]; } [super drawRect:rect]; } @end
第二种方法:原理是通过Placeholder字符串的长度,当textView输入内容时,Placeholder 字符串的长度为nil,当textView不输入内容时,Placeholder显示。
#import <UIKit/UIKit.h> @interface DLTextView : UITextView @property (nonatomic, copy) NSString *placeholder; @end
#import "DLTextView.h" @implementation DLTextView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setup]; } return self; } - (instancetype)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (self) { [self setup]; } return self; } - (void)awakeFromNib { // [self setup]; } - (void)setup { // NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:super.text]; // NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; // paragraphStyle.lineSpacing = 10; // // [attributedText addAttributes:@{NSParagraphStyleAttributeName : paragraphStyle} range:NSMakeRange(0, super.text.length)]; // // super.attributedText = attributedText; // 添加通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewDidBeginEditing:) name:UITextViewTextDidBeginEditingNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewDidEndEditing:) name:UITextViewTextDidEndEditingNotification object:nil]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - 开始编辑的消息方法 - (void)textViewDidBeginEditing:(NSNotification *)sender { // 开始编辑的时候,父控件的text如果等于placeholder就让什么也不显示 if ([super.text isEqualToString:self.placeholder]) { super.text = @""; [super setTextColor:[UIColor blackColor]]; } } - (void)textViewDidEndEditing:(NSNotification *)sender { if (super.text.length == 0) { super.text = self.placeholder; [super setTextColor:[UIColor grayColor]]; } } - (void)setPlaceholder:(NSString *)placeholder { _placeholder = placeholder; // 调用通知的方法,让placeholder显示在UI上面 [self textViewDidEndEditing:nil]; } #pragma mark - 重写父类的text方法 - (NSString *)text { if ([super.text isEqualToString:self.placeholder]) { super.text = @""; } return super.text; } @end