由于在项目中使用自动换行输入框的场景比较多,所以就自己封了个自动换行的输入框。具体步骤,且由我一一道来。
在苹果本身控件中,UITextView是不具备placeholder的功能,所以我们需要自己重写一下UITextView,让他具备placeholder的功能。
效果图:
Untitled.gif直接上代码:
#import <UIKit/UIKit.h>
#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
#define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
@interface ZXTextView : UITextView
@property(nullable, nonatomic,copy) IBInspectable NSString *placeholder;
@end
#import "ZXTextView.h"
@interface ZXTextView ()
-(void)refreshPlaceholder;
@end
@implementation ZXTextView
{
UILabel *placeHolderLabel;
}
@synthesize placeholder = _placeholder;
-(void)initialize
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshPlaceholder) name:UITextViewTextDidChangeNotification object:self];
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (instancetype)init
{
self = [super init];
if (self) {
[self initialize];
}
return self;
}
-(void)awakeFromNib
{
[super awakeFromNib];
[self initialize];
}
-(void)refreshPlaceholder
{
if([[self text] length])
{
[placeHolderLabel setAlpha:0];
}
else
{
[placeHolderLabel setAlpha:1];
}
[self setNeedsLayout];
[self layoutIfNeeded];
}
- (void)setText:(NSString *)text
{
[super setText:text];
[self refreshPlaceholder];
}
-(void)setFont:(UIFont *)font
{
[super setFont:font];
placeHolderLabel.font = self.font;
[self setNeedsLayout];
[self layoutIfNeeded];
}
-(void)layoutSubviews
{
[super layoutSubviews];
[placeHolderLabel sizeToFit];
placeHolderLabel.frame = CGRectMake(self.textContainerInset.left + 5,self.textContainerInset.top, CGRectGetWidth(self.frame)-16, CGRectGetHeight(placeHolderLabel.frame));
}
-(void)setPlaceholder:(NSString *)placeholder
{
_placeholder = placeholder;
if ( placeHolderLabel == nil )
{
placeHolderLabel = [[UILabel alloc] init];
placeHolderLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping;
placeHolderLabel.numberOfLines = 0;
placeHolderLabel.font = self.font;
placeHolderLabel.backgroundColor = [UIColor clearColor];
placeHolderLabel.textColor = [UIColor colorWithWhite:0.7 alpha:1.0];
placeHolderLabel.alpha = 0;
[self addSubview:placeHolderLabel];
}
placeHolderLabel.text = self.placeholder;
[self refreshPlaceholder];
}
-(id<UITextViewDelegate>)delegate
{
[self refreshPlaceholder];
return [super delegate];
}
@end
接下来要做的有两件事,一为监听键盘并实时改变ZXTextView的位置,二为根据文字实时改变ZXTextView的高度。代码如下:
#import <UIKit/UIKit.h>
@class ZXTextView;
@interface ZXLayoutTextView : UIView
@property (weak, nonatomic) ZXTextView *textView;
@property (copy, nonatomic) NSString *placeholder;
@property (copy, nonatomic) void (^(sendBlock)) (ZXTextView *textView);
@end
#import "ZXLayoutTextView.h"
#import "ZXTextView.h"
#define kTextViewFont [UIFont systemFontOfSize:17]
static CGFloat maxHeight = 80.0f;
static CGFloat leftFloat = 10.0f;
static CGFloat textViewHFloat = 36.0f;
@interface ZXLayoutTextView()<UITextViewDelegate>
@property (assign, nonatomic) CGFloat superHight;
@property (assign, nonatomic) CGFloat textViewY;
@property (assign, nonatomic) CGFloat keyBoardHight;
@property (assign, nonatomic) CGRect originalFrame;
@property (copy,nonatomic) NSString *lastText;
@end
@implementation ZXLayoutTextView
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
_originalFrame = frame;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShow:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
self.backgroundColor = [UIColor whiteColor];
ZXTextView *textView = [[ZXTextView alloc] init];
textView.delegate = self;
textView.placeholder = _placeholder;
textView.backgroundColor = [UIColor whiteColor];
textView.font = kTextViewFont;
textView.layer.cornerRadius = 5;
textView.layer.masksToBounds = YES;
textView.layer.borderWidth = 0.5;
textView.returnKeyType = UIReturnKeySend;
textView.layer.borderColor = [[UIColor grayColor] CGColor];
textView.layoutManager.allowsNonContiguousLayout = NO;
[self addSubview:textView];
self.textView = textView;
CGFloat textViewX = leftFloat;
CGFloat textViewW = SCREEN_WIDTH-2*textViewX;
CGFloat textViewH = textViewHFloat;
CGFloat textViewY = (self.frame.size.height-textViewH)*0.5;
_textView.frame = CGRectMake(textViewX, textViewY, textViewW, textViewH);
_textViewY = textViewY;
_superHight = self.frame.size.height;
}
return self;
}
- (void)layoutSubviews{
[super layoutSubviews];
self.textView.placeholder = _placeholder;
}
#pragma mark - == UITextViewDelegate
- (void)textViewDidBeginEditing:(UITextView *)textView{
self.lastText = @"";
_textView.placeholder = _placeholder;
}
- (void)textViewDidChange:(UITextView *)textView{
CGRect frame = textView.frame;
CGSize constraintSize = CGSizeMake(frame.size.width, MAXFLOAT);
CGSize size = [textView sizeThatFits:constraintSize];
if (size.height<=frame.size.height) {
}else{
if (size.height>=maxHeight){
size.height = maxHeight;
textView.scrollEnabled = YES; // 允许滚动
}else{
textView.scrollEnabled = NO; // 不允许滚动
}
}
textView.frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, size.height);
CGFloat superHeight = CGRectGetMaxY(textView.frame)+_textViewY;
[UIView animateWithDuration:0 animations:^{
[self setFrame:CGRectMake(self.frame.origin.x, SCREEN_HEIGHT-(_keyBoardHight+superHeight), self.frame.size.width, superHeight)];
}];
CGFloat h = [self heightForString:textView.text fontSize:17];
if (textView.text.length >self.lastText.length+5) {
if (h>maxHeight) {
[textView setContentOffset:CGPointMake(0, (h-maxHeight)) animated:NO];
}
}
self.lastText = textView.text;
}
-(float)heightForString:(NSString *)value fontSize:(float)fontSize{
NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:fontSize]};
CGSize size = [value boundingRectWithSize:CGSizeMake(SCREEN_WIDTH-20, CGFLOAT_MAX) options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attribute context:nil].size;
return size.height;
}
- (void)textViewDidChangeSelection:(UITextView *)textView{
CGRect r = [textView caretRectForPosition:textView.selectedTextRange.end];
CGFloat caretY = MAX(r.origin.y - textView.frame.size.height + r.size.height + 8, 0);
if (textView.contentOffset.y < caretY && r.origin.y != INFINITY) {
textView.contentOffset = CGPointMake(0, caretY);
}
}
- (void)textViewDidEndEditing:(UITextView *)textView{
textView.scrollEnabled = NO;
CGRect frame = textView.frame;
textView.frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, textViewHFloat);
[textView layoutIfNeeded];
[_textView resignFirstResponder];
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text {
if ([text isEqualToString:@"\n"]){
NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSString *str = [[NSString alloc]initWithString:[textView.text stringByTrimmingCharactersInSet:whiteSpace]];
if (str.length != 0) {
if (_sendBlock) {
_sendBlock(_textView);
[_textView resignFirstResponder];
_textView.placeholder = _placeholder;
}
}
return NO;
}
return YES;
}
#pragma mark - == 键盘弹出事件
- (void)keyboardWasShow:(NSNotification*)notification{
CGRect keyBoardFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
_keyBoardHight = keyBoardFrame.size.height;
[self translationWhenKeyboardDidShow:_keyBoardHight];
}
- (void)keyboardWillBeHidden:(NSNotification*)notification{
self.textView.placeholder = _placeholder;
[self translationWhenKeyBoardDidHidden];
}
- (void)translationWhenKeyboardDidShow:(CGFloat)keyBoardHight{
[UIView animateWithDuration:0 animations:^{
self.frame = CGRectMake(self.frame.origin.x, SCREEN_HEIGHT - (keyBoardHight+self.frame.size.height), self.frame.size.width, self.frame.size.height);
}];
}
- (void)translationWhenKeyBoardDidHidden{
[UIView animateWithDuration:0 animations:^{
self.frame = _originalFrame;
}];
}
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
封装完了之后,接下来就可以调用了。方法 so easy,如下:
#import "ViewController.h"
#import "ZXLayoutTextView.h"
#import "ZXTextView.h"
#define RGB_COLOR(r, g, b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1.0]
@interface ViewController ()
@property (nonatomic,strong) ZXLayoutTextView *commentView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_commentView = [[ZXLayoutTextView alloc] initWithFrame:CGRectMake(0, SCREEN_HEIGHT-60, SCREEN_WIDTH, 60.0f)];
_commentView.backgroundColor = RGB_COLOR(245, 245, 245);
typeof(self) weakSelf = self;
[_commentView setSendBlock:^(ZXTextView *textView) {
weakSelf.commentView.textView.text = @"";
}];
[self.view addSubview:_commentView];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
self.commentView.placeholder = @"评论";
[self.commentView.textView becomeFirstResponder];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
以上就是自动换行输入框的整个创建流程,希望能对大家有用。
网友评论