1. 程式人生 > >iOS之UITextView實現placeHolder佔位文字的最佳方法

iOS之UITextView實現placeHolder佔位文字的最佳方法

在iOS開發中,UITextField和UITextView是最常用的文字輸入類和文字展示類的控制元件。不同的是,UITextField中有一個placeholder屬性,可以設定UITextField的佔位文字,可是,Apple沒有給UITextView公開提供一個類似於placeholder這樣的屬性來供開發者使用。但是,通過Runtime,我們發現,UITextView內部有個“_placeHolderLabel”的私有成員變數。這種方法有一定的風險,而且可移植性不強。
筆者參考了各種方法,推薦下面自定義的UITextView,不僅可移植性強、而且拓展性好,還可以隨時修改自定義屬性的值,我們只需要自定義一個UITextView,就可以一勞永逸了。

.h檔案
@interface UITextViewPlaceholder : UITextView

/* 佔位文字 /
@property (copy, nonatomic) NSString *placeholder;
/* 佔位文字顏色 /
@property (strong, nonatomic) UIColor *placeholderColor;

@end

.m檔案
@implementation UITextViewPlaceholder
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// 設定預設字型
self.font = [UIFont systemFontOfSize:14];
// 設定預設顏色
self.placeholderColor = [UIColor lightGrayColor];
// 使用通知監聽文字改變
[[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 = 5;
rect.origin.y = 8;
rect.size.width -= 2 * 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