PlaceholderTextView
效果
源码
https://github.com/YouXianMing/UI-Component-Collection 的 PlaceholderTextView
// // PlaceholderTextView.h // PlaceholderTextView // // Created by YouXianMing on 16/7/18. // Copyright © 2016年 YouXianMing. All rights reserved. // #import@class PlaceholderTextView; @protocol PlaceholderTextViewDelegate @optional /** * Asks the delegate if editing should begin in the specified text view. * * @param textView PlaceholderTextView's object. * * @return YEStrue if an editing session should be initiated; otherwise, NOfalse to disallow editing. */ - (BOOL)placeholderTextViewShouldBeginEditing:(PlaceholderTextView *)textView; /** * Asks the delegate if editing should stop in the specified text view. * * @param textView PlaceholderTextView's object. * * @return YEStrue if editing should stop; otherwise, NOfalse if the editing session should continue */ - (BOOL)placeholderTextViewShouldEndEditing:(PlaceholderTextView *)textView; /** * Tells the delegate that editing of the specified text view has begun. * * @param textView PlaceholderTextView's object. */ - (void)placeholderTextViewDidBeginEditing:(PlaceholderTextView *)textView; /** * Tells the delegate that editing of the specified text view has ended. * * @param textView PlaceholderTextView's object. */ - (void)placeholderTextViewDidEndEditing:(PlaceholderTextView *)textView; /** * Asks the delegate whether the specified text should be replaced in the text view. * * @param textView PlaceholderTextView's object. * * @return YEStrue if the old text should be replaced by the new text; NOfalse if the replacement operation should be aborted. */ - (BOOL)placeholderTextShouldChangeText:(PlaceholderTextView *)textView; @end @interface PlaceholderTextView : UIView /** * PlaceholderTextView's delegate. */ @property (nonatomic, weak) id delegate; /** * Current string. */ @property (nonatomic, strong, readonly) NSString *currentString; #pragma mark - UITextView related. /** * The TextView. */ @property (nonatomic, strong, readonly) UITextView *textView; /** * The textView's containerInset. */ @property (nonatomic) UIEdgeInsets textContainerInset; #pragma mark - Placeholder related. /** * Placeholder attributed string. */ @property (nonatomic, strong) NSAttributedString *attributedPlaceholder; /** * PlaceHorderString gap from left. */ @property (nonatomic) CGFloat placeHorderLeftEdge; /** * PlaceHorderString gap from top. */ @property (nonatomic) CGFloat placeHorderTopEdge; #pragma mark - PlaceholderTextView's event. /** * PlaceholderTextView resign first responder. */ - (void)placeholderTextViewResignFirstResponder; /** * PlaceholderTextView become first responder. */ - (void)placeholderTextViewbecomeFirstResponder; @end
// // PlaceholderTextView.m // PlaceholderTextView // // Created by YouXianMing on 16/7/18. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "PlaceholderTextView.h" @interface PlaceholderTextView ()@property (nonatomic, strong) UITextField *textField; @property (nonatomic, strong) UITextView *textView; @property (nonatomic, strong) NSString *currentString; @end @implementation PlaceholderTextView #pragma mark - Frame related method. - (void)layoutSubviews { [super layoutSubviews]; self.textView.frame = self.bounds; [self resetPlaceHorderFrame]; } - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.textField = [[UITextField alloc] init]; self.textField.enabled = NO; self.textField.textColor = [UIColor clearColor]; [self addSubview:self.textField]; self.textView = [[UITextView alloc] initWithFrame:self.bounds]; self.textView.delegate = self; self.textView.backgroundColor = [UIColor clearColor]; self.textView.textColor = [UIColor grayColor]; [self addSubview:self.textView]; } return self; } #pragma mark - FirstResponder related. - (void)placeholderTextViewResignFirstResponder { [self.textView resignFirstResponder]; } - (void)placeholderTextViewbecomeFirstResponder { [self.textView becomeFirstResponder]; } #pragma mark - UITextViewDelegate - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { NSString *currentText = [textView.text stringByReplacingCharactersInRange:range withString:text]; self.textField.text = currentText; self.currentString = currentText; if (self.delegate && [self.delegate respondsToSelector:@selector(placeholderTextShouldChangeText:)]) { return [self.delegate placeholderTextShouldChangeText:self]; } else { return YES; } } - (BOOL)textViewShouldBeginEditing:(UITextView *)textView { if (self.delegate && [self.delegate respondsToSelector:@selector(placeholderTextViewShouldBeginEditing:)]) { return [self.delegate placeholderTextViewShouldBeginEditing:self]; } else { return YES; } } - (BOOL)textViewShouldEndEditing:(UITextView *)textView { if (self.delegate && [self.delegate respondsToSelector:@selector(placeholderTextViewShouldEndEditing:)]) { return [self.delegate placeholderTextViewShouldEndEditing:self]; } else { return YES; } } - (void)textViewDidBeginEditing:(UITextView *)textView { if (self.delegate && [self.delegate respondsToSelector:@selector(placeholderTextViewDidBeginEditing:)]) { [self.delegate placeholderTextViewDidBeginEditing:self]; } } - (void)textViewDidEndEditing:(UITextView *)textView { if (self.delegate && [self.delegate respondsToSelector:@selector(placeholderTextViewDidEndEditing:)]) { [self.delegate placeholderTextViewDidEndEditing:self]; } } #pragma mark - PlaceHorder related - (void)resetPlaceHorderFrame { self.textField.attributedPlaceholder = _attributedPlaceholder; [self.textField sizeToFit]; CGRect newFrame = self.textField.frame; newFrame.origin.x = _placeHorderLeftEdge; newFrame.origin.y = _placeHorderTopEdge; self.textField.frame = newFrame; } #pragma mark - Setter & Getter - (void)setTextContainerInset:(UIEdgeInsets)textContainerInset { _textContainerInset = textContainerInset; _textView.textContainerInset = textContainerInset; } - (void)setPlaceHorderLeftEdge:(CGFloat)placeHorderLeftEdge { _placeHorderLeftEdge = placeHorderLeftEdge; [self resetPlaceHorderFrame]; } - (void)setPlaceHorderTopEdge:(CGFloat)placeHorderTopEdge { _placeHorderTopEdge = placeHorderTopEdge; [self resetPlaceHorderFrame]; } - (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder { _attributedPlaceholder = attributedPlaceholder; [self resetPlaceHorderFrame]; } @end
// // PlaceholderTextView+ConvenientSetup.h // PlaceholderTextView // // Created by YouXianMing on 16/7/18. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "PlaceholderTextView.h" @interface PlaceholderTextView (ConvenientSetup) /** * PlaceholderTextView's placeholderString setup. * * @param string The placeholderString. * @param font Font. * @param color Color. * @param leftEdge Gap from left. * @param topEdge Gap from top. */ - (void)placeholderString:(NSString *)string font:(UIFont *)font color:(UIColor *)color leftEdge:(CGFloat)leftEdge topEdge:(CGFloat)topEdge; /** * PlaceholderTextView's textView setup. * * @param font Font. * @param color Color. * @param containerInset TextContainerInset. */ - (void)textViewFont:(UIFont *)font color:(UIColor *)color containerInset:(UIEdgeInsets)containerInset; /** * Create the InputAccessoryView with the specified heigh. * * @param height The view's height. * * @return InputAccessoryView. */ - (UIView *)createInputAccessoryViewWithViewHeight:(CGFloat)height; @end
// // PlaceholderTextView+ConvenientSetup.m // PlaceholderTextView // // Created by YouXianMing on 16/7/18. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "PlaceholderTextView+ConvenientSetup.h" @implementation PlaceholderTextView (ConvenientSetup) - (void)placeholderString:(NSString *)string font:(UIFont *)font color:(UIColor *)color leftEdge:(CGFloat)leftEdge topEdge:(CGFloat)topEdge { NSParameterAssert(string); NSParameterAssert(font); NSParameterAssert(color); NSString *placeHorderString = string; NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:placeHorderString]; [attributeString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, placeHorderString.length)]; [attributeString addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, placeHorderString.length)]; self.placeHorderLeftEdge = leftEdge; self.placeHorderTopEdge = topEdge; self.attributedPlaceholder = attributeString; } - (void)textViewFont:(UIFont *)font color:(UIColor *)color containerInset:(UIEdgeInsets)containerInset { self.textView.font = font; self.textView.textColor = color; self.textContainerInset = containerInset; } - (UIView *)createInputAccessoryViewWithViewHeight:(CGFloat)height { UIView *inputAccessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, height)]; inputAccessoryView.backgroundColor = [UIColor clearColor]; self.textView.inputAccessoryView = inputAccessoryView; return inputAccessoryView; } @end
// // ViewController.m // PlaceholderTextView // // Created by YouXianMing on 16/7/18. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "PlaceholderTextView.h" #import "PlaceholderTextView+ConvenientSetup.h" @interface ViewController (){ PlaceholderTextView *_textView; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIColor *grayColor = [UIColor grayColor]; UIColor *textColor = [[UIColor blackColor] colorWithAlphaComponent:0.95f]; UIColor *whiteColor = [UIColor whiteColor]; UIFont *font_16 = [UIFont systemFontOfSize:16.f]; // Add UITapGestureRecognizer. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureEvent)]; [self.view addGestureRecognizer:tapGesture]; // Create PlaceholderTextView. _textView = [[PlaceholderTextView alloc] initWithFrame:CGRectMake(0, 20, 320, 180)]; _textView.layer.borderWidth = 0.5f; _textView.delegate = self; [self.view addSubview:_textView]; // Set placeholderString. [_textView placeholderString:@"请输入您的评价(少于50字)" font:font_16 color:grayColor leftEdge:19.f topEdge:15.f]; // Set textView. [_textView textViewFont:font_16 color:textColor containerInset:UIEdgeInsetsMake(15.f, 15.f, 15.f, 15.f)]; // Create inputAccessoryView. UIView *inputAccessoryView = [_textView createInputAccessoryViewWithViewHeight:40.f]; inputAccessoryView.backgroundColor = grayColor; // Setup inputAccessoryView. UIButton *button = [[UIButton alloc] initWithFrame:inputAccessoryView.bounds]; button.titleLabel.font = [UIFont systemFontOfSize:14.f]; [button setTitle:@"确定" forState:UIControlStateNormal]; [button setTitleColor:whiteColor forState:UIControlStateNormal]; [button setTitleColor:[whiteColor colorWithAlphaComponent:0.5f] forState:UIControlStateHighlighted]; [button addTarget:self action:@selector(inputAccessoryViewEvent) forControlEvents:UIControlEventTouchUpInside]; [inputAccessoryView addSubview:button]; } #pragma mark - Event related. - (void)inputAccessoryViewEvent { [_textView placeholderTextViewResignFirstResponder]; } - (void)gestureEvent { [self.view endEditing:YES]; } #pragma mark - PlaceholderTextViewDelegate - (BOOL)placeholderTextShouldChangeText:(PlaceholderTextView *)textView { NSLog(@"--> %@", textView.currentString); BOOL result; textView.currentString.length >= 50 ? (result = NO) : (result = YES); return result; } - (BOOL)placeholderTextViewShouldBeginEditing:(PlaceholderTextView *)textView { NSLog(@"placeholderTextViewShouldBeginEditing"); return YES; } - (BOOL)placeholderTextViewShouldEndEditing:(PlaceholderTextView *)textView { NSLog(@"placeholderTextViewShouldEndEditing"); return YES; } - (void)placeholderTextViewDidBeginEditing:(PlaceholderTextView *)textView { NSLog(@"placeholderTextViewDidBeginEditing"); } - (void)placeholderTextViewDidEndEditing:(PlaceholderTextView *)textView { NSLog(@"placeholderTextViewDidEndEditing"); } #pragma mark - System method. - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [_textView placeholderTextViewbecomeFirstResponder]; } @end