思路是将一个label作为placeholder放在textview上
textview添加观察者来观察textview的text变化 通过textview的 text变化来修改作为placeholder的label
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIPlaceHolderTV : UITextView
/**
占位符
*/
@property (nonatomic, strong) NSString *placeholder;
/**
占位符颜色
*/
@property (nonatomic, strong) UIColor *placeholderColor;
/**
文字改变
@param notification 通知
*/
-(void)textChanged:(NSNotification*)notification;
/**
初始化方法
@param frame frame
@param adaption 是否自动适应大小
@return self
*/
- (id)initWithFrame:(CGRect)frame adaption:(BOOL)adaption;
@property (nonatomic, strong) UILabel *placeHolderLabel;
@end
#import "UIPlaceHolderTV.h"
@interface UIPlaceHolderTV()<UITextViewDelegate>
@end
@implementation UIPlaceHolderTV
CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25;
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)awakeFromNib{
[super awakeFromNib];
if (!self.placeholder) {
_placeholder = @"";
}
if (!self.placeholderColor) {
[self setPlaceholderColor:[UIColor colorWithRed:203/255.0 green:203/255.0 blue:203/255.0 alpha:1]];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
}
- (id)initWithFrame:(CGRect)frame adaption:(BOOL)adaption {
if( (self = [super initWithFrame:frame]) ){
_placeholder = @"";
[self setPlaceholderColor:[UIColor colorWithRed:203/255.0 green:203/255.0 blue:203/255.0 alpha:1]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
if (adaption) {
self.delegate = self;
}
}
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 ){
UIEdgeInsets insets = self.textContainerInset;
_placeHolderLabel.text = self.placeholder;
[_placeHolderLabel sizeToFit];
[_placeHolderLabel setFrame:CGRectMake(insets.left+5,insets.top,self.bounds.size.width - (insets.left +insets.right+10),CGRectGetHeight(_placeHolderLabel.frame))];
[self sendSubviewToBack:_placeHolderLabel];
}
if( [[self text] length] == 0 && [[self placeholder] length] > 0 ){
[[self viewWithTag:999] setAlpha:1];
}
[super drawRect:rect];
}
- (void)setPlaceholder:(NSString *)placeholder{
if (_placeholder != placeholder) {
_placeholder = placeholder;
[self setNeedsDisplay];
UIEdgeInsets insets = self.textContainerInset;
if (_placeHolderLabel == nil )
{
_placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(insets.left+5,insets.top,self.bounds.size.width - (insets.left +insets.right+10),1.0)];
_placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping;
_placeHolderLabel.font = self.font;
_placeHolderLabel.backgroundColor = [UIColor clearColor];
_placeHolderLabel.textColor = self.placeholderColor;
_placeHolderLabel.alpha = 0;
_placeHolderLabel.tag = 999;
[self addSubview:_placeHolderLabel];
}
}
}
//计算输入文字高度的方法,之所以返回的高度值加22是因为UITextView有一个初始的高度值40,但是输入第一行文字的时候文字高度只有18,所以UITextView的高度会发生变化,效果不太好
- (float) heightForTextView: (UITextView *)textView WithText: (NSString *) strText{
CGSize constraint = CGSizeMake(textView.contentSize.width , CGFLOAT_MAX);
CGRect size = [strText boundingRectWithSize:constraint options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14]}
context:nil];
float textHeight = size.size.height + 22.0;
return textHeight;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
CGRect frame = textView.frame;
float height;
if ([text isEqual:@""]) {
if (![textView.text isEqualToString:@""]) {
height = [ self heightForTextView:textView WithText:[textView.text substringToIndex:[textView.text length] - 1]];
}else{
height = [ self heightForTextView:textView WithText:textView.text];
}
}else{
height = [self heightForTextView:textView WithText:[NSString stringWithFormat:@"%@%@",textView.text,text]];
}
frame.size.height = height;
[UIView animateWithDuration:0.5 animations:^{
textView.frame = frame;
} completion:nil];
return YES;
}
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender {
UIMenuController *menuController = [UIMenuController sharedMenuController];
if (menuController) {
[UIMenuController sharedMenuController].menuVisible = NO;
}
return NO;
}
- (BOOL)canBecomeFirstResponder
{
return self.editable;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
网友评论