天天看點

ios 自定義帶占位文字(placeholder)的TextView

小夥伴們在寫輸入框的時候很可能需要帶占位文字的TextView,由于TextField控件有占位文字的屬性,但它不能多行顯示,而TextView可以多行顯示,但是它又沒有占位文字屬性,是以我們隻能自定義TextView控件了:

首先說一下思路:要定義這控件還是很簡單,關鍵是一些細節上的處理問題(要讓外部用起來很爽)。首先,讓該控件繼承自TextView,然後在這個TextView上加一個UILabel子控件,當使用者點選TextView準備輸入或TextView中有文字時,隐藏Label,沒有文字時顯示Label。當我們在監聽TextView中的文字變化時,第一時間想到的肯定是設定代理,并讓自己為代理,但這樣的設計和蘋果的代理模式相悖,能用但不合理這樣設計不好,應該采取發通知的方式來監聽TextView中的文字變化。

首先,初始化時加入Label:

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor clearColor];
        
        //添加一個顯示占位文字的Label
        UILabel *placeholderLabel = [[UILabel alloc]init];
        placeholderLabel.backgroundColor = [UIColor clearColor];
        placeholderLabel.numberOfLines = 0;
        [self addSubview:placeholderLabel];
        
        self.placeholderLabel = placeholderLabel;
        
        //設定占位文字顔色
        self.placeholderColor = [UIColor lightGrayColor];
        //設定預設字型
        self.font = [UIFont systemFontOfSize:15];
        
        //設定監聽通知,不要設定自己的代理為本身
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextViewTextDidChangeNotification object:self];
    }
    return self;
}
           

加入通知監聽後,為防止記憶體洩露,要将其移除

/**
 *  移除通知監聽
 */
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
           

布局子控件:

/**
 *  文字内容改變時調用的方法
 */
- (void)textChange {
    self.placeholderLabel.hidden = (self.text.length != 0);
}

/**
 *  布局子控件
 */
- (void)layoutSubviews {
    [super layoutSubviews];
    CGFloat placeholderLabelX = 5;
    CGFloat placeholderLabelY = 8;
    CGFloat placeholderLabelWidth = self.frame.size.width - 2 * placeholderLabelX;
    CGFloat placeholderLabelHeight = [self.placeholder boundingRectWithSize:CGSizeMake(placeholderLabelWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.placeholderLabel.font}  context:nil].size.height;
    self.placeholderLabel.frame = CGRectMake(placeholderLabelX, placeholderLabelY, placeholderLabelWidth, placeholderLabelHeight);
}

- (void)setPlaceholder:(NSString *)placeholder {
    
    //copy政策的話setter應該這樣寫
    _placeholder = [placeholder copy];
    self.placeholderLabel.text = placeholder;
    //由于字元數變化,需要重新布局
    [self setNeedsLayout];
}

- (void)setPlaceholderColor:(UIColor *)placeholderColor {
    _placeholderColor = placeholderColor;
    self.placeholderLabel.textColor = placeholderColor;
}

- (void)setFont:(UIFont *)font {
    [super setFont:font];
    self.placeholderLabel.font = font;
    [self setNeedsLayout];
}

- (void)setText:(NSString *)text {
    [super setText:text];
    
    [self textChange];
}
           

最後附上demo位址:http://download.csdn.net/detail/u013672551/9145287

iOS