UITextView实现PlaceHolder的方式

实现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

  

posted on 2016-05-12 16:26  村里竹竿  阅读(805)  评论(0编辑  收藏  举报