//.h文件
#import <UIKit/UIKit.h>
@interface XYLPlaceHodlerTextView : UITextView
/**placeholder占位文字*/
@property (nonatomic, copy) NSString *placeholder;
/**placeholderColor占位文字颜色*/
@property (nonatomic, strong) UIColor *placeholderColor;
@end
// .m文件
#import "XYLPlaceHodlerTextView.h"
@interface XYLPlaceHodlerTextView()
/**UILabel*/
@property (nonatomic, strong) UILabel *placeholderLabel;
@end
@implementation XYLPlaceHodlerTextView
/**
* 懒加载属性,并设置属性的值
*/
-(UILabel *)placeholderLabel
{
if (!_placeholderLabel) {
UILabel *label = [[UILabel alloc]init];
label.font = [UIFont systemFontOfSize:14];
label.textColor = [UIColor grayColor];
label.numberOfLines = 0;
_placeholderLabel = label;
}
return _placeholderLabel;
}
/**
* 设置自己的属性
*/
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.alwaysBounceVertical = YES;
self.textColor = [UIColor blackColor];
[XYLNotificationCenter addObserver:self selector:@selector(texting) name:UITextViewTextDidChangeNotification object:self];
}
return self;
}
/**
* 监听有文字输入
*/
-(void)texting
{
[self setPlaceholderTextShow];
}
/**
* 设置占位文字的显示
*/
-(void)setPlaceholderTextShow
{
self.placeholderLabel.hidden = self.hasText;
}
-(void)layoutSubviews
{
[super layoutSubviews];
self.placeholderLabel.x = 4;
self.placeholderLabel.y = 8;
self.placeholderLabel.width = self.width - 22 * self.placeholderLabel.x;
[self.placeholderLabel sizeToFit];//这一步很重要,不能遗忘
}
-(void)setPlaceholder:(NSString *)placeholder
{
// _placeholder = placeholder;//此句的意义何在?
self.placeholderLabel.text = placeholder;
[self setNeedsLayout];
}
-(void)setPlaceholderColor:(UIColor *)placeholderColor
{
self.placeholderLabel.textColor = placeholderColor;
[self setNeedsLayout];
}
-(void)setFont:(UIFont *)font
{
[super setFont:font];
self.placeholderLabel.font = font;
[self setNeedsLayout];
}
-(void)setText:(NSString *)text
{
[super setText:text];
[self setPlaceholderTextShow];
}
-(void)setAttributedText:(NSAttributedString *)attributedText
{
[super setAttributedText:attributedText];
[self setPlaceholderTextShow];
}
@end
注意点:
界面显示步骤是先调用layoutSubviews将所有子控件的位置frame设计好,然后再调用drawRect方法画上去。
layoutSubviews的调用时机:
init时不会被调用
将要真正显示的会调用
frame发现改变时智能调用
滚动、旋转、remove等等时
这些时机都是和frame相关的,也是唯一能更新子视图的最好时机