目前能夠實現的功能:
- 設置佔位字符,可以設置佔位字符的字體大小,字體顏色,字體高亮顏色,也可以設置屬性字符串作爲佔位字符
- 設置最大行數,超過最大行數之後滾動顯示
- 設置最多輸入的文字個數,超過之後不能輸入,並觸發block回調
- 設置輸入框的圓角弧度
- 設置光標的寬度和高度
直接上代碼:
.h文件:
//
// KPTextView.h
//
// 使用時至少實現 佔位文字內容 和 文字的字體大小
//
// Created by 劉鯤鵬 on 2017/5/12.
// Copyright © 2017年 劉鯤鵬. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef void(^KP_textHeightChangedBlock)(NSString *text,CGFloat textHeight);
typedef void(^KP_textViewLengthOverLimitBlock)(NSInteger maxLengthOfText);
@interface KPTextView : UITextView
/**
* 普通字符串 佔位文字
*/
@property (nonatomic, strong) NSString *placeholder;
/**
* 屬性字符串 佔位文字
*/
@property (nonatomic, strong) NSAttributedString *attributedPlaceHolder;
/**
* 佔位文字顏色,默認爲亮灰色
*/
@property (nonatomic, strong) UIColor *placeholderColor;
/**
* 佔位文字高亮顏色,默認爲亮灰色
*/
@property (nonatomic, strong) UIColor *placeholderHighLightColor;
/**
* 佔位符字體大小
*/
@property (nonatomic,strong) UIFont *placeholderFont;
/**
* textView最大行數,默認沒有高度限制
*/
@property (nonatomic, assign) NSUInteger maxNumberOfLines;
/**
* textView可以輸入的最大字數,默認沒有字數限制
*/
@property (nonatomic, assign) NSUInteger maxLengthOfText;
/**
* 設置邊框寬度,默認爲1
*/
@property (nonatomic, assign) NSUInteger borderWidth;
/**
* 設置邊框顏色,默認爲亮灰色
*/
@property (nonatomic, strong) UIColor *borderColor;
/**
* 設置圓角,默認沒有圓角
*/
@property (nonatomic, assign) NSUInteger cornerRadius;
/**
* 光標寬度,默認爲2
*/
@property (nonatomic, assign) NSUInteger cursorWidth;
/**
* 光標高度,默認爲 self.font.lineHeight + 4
*/
@property (nonatomic, assign) NSUInteger cursorHeight;
/**
* 文字高度改變會自動調用
* block參數(text) → 文字內容
* block參數(textHeight) → 文字高度
*/
@property (nonatomic, strong) KP_textHeightChangedBlock textChangedBlock;
/**
* 文字字數超出設定值會自動調用
* block參數(maxLengthOfText) → 文字長度最大值
*/
@property (nonatomic, strong) KP_textViewLengthOverLimitBlock textOverLimitBlock;
- (void)textValueDidChanged:(KP_textHeightChangedBlock)block;
- (void)textLengthOverLimit:(KP_textViewLengthOverLimitBlock)block;
@end
.m文件:
//
// KPTextView.m
// textViewDemo
//
// Created by 劉鯤鵬 on 2017/5/12.
// Copyright © 2017年 劉鯤鵬. All rights reserved.
//
#import "KPTextView.h"
@interface KPTextView ()
{
UIColor *NormalColor;
}
/**
* UILabel作爲placeholderView,解決佔位符問題.
*/
@property (nonatomic, weak) UILabel *placeholderView;
/**
* 文字高度
*/
@property (nonatomic, assign) NSInteger textH;
/**
* 文字最大高度
*/
@property (nonatomic, assign) NSInteger maxTextH;
/**
* textView設定的高度
*/
@property (nonatomic, assign) NSInteger textViewSettingHeight;
@end
@implementation KPTextView
- (UILabel *)placeholderView {
if (!_placeholderView ) {
UILabel *placeholderView = [[UILabel alloc] init];
_placeholderView = placeholderView;
//防止textView輸入時跳動問題
// _placeholderView.scrollEnabled = NO;
// _placeholderView.showsHorizontalScrollIndicator = NO;
// _placeholderView.showsVerticalScrollIndicator = NO;
_placeholderView.userInteractionEnabled = NO;
_placeholderView.font = self.font;
_placeholderView.backgroundColor = [UIColor clearColor];
_placeholderColor = [UIColor lightGrayColor];
_placeholderView.textColor = _placeholderColor;
_placeholderView.numberOfLines = 0;
_maxNumberOfLines = NSIntegerMax;
[self addSubview:placeholderView];
}
return _placeholderView;
}
- (void)setMaxNumberOfLines:(NSUInteger)maxNumberOfLines {
_maxNumberOfLines = maxNumberOfLines;
/**
* 根據最大的行數計算textView的最大高度
* 計算最大高度 = (每行高度 * 總行數 + 文字上下間距)
*/
_maxTextH = ceil(self.font.lineHeight * maxNumberOfLines + self.textContainerInset.top + self.textContainerInset.bottom);
}
- (void)setBorderWidth:(NSUInteger)borderWidth {
_borderWidth = borderWidth;
self.layer.borderWidth = _borderWidth;
}
- (void)setBorderColor:(UIColor *)borderColor {
_borderColor = borderColor;
self.layer.borderColor = _borderColor.CGColor;
}
- (void)setCornerRadius:(NSUInteger)cornerRadius {
_cornerRadius = cornerRadius;
self.layer.cornerRadius = cornerRadius;
}
/**
* 通過設置placeholderColor設置私有屬性placeholderView中的textColor
*/
- (void)setPlaceholderColor:(UIColor *)placeholderColor {
static dispatch_once_t once;
dispatch_once(&once, ^{
NormalColor = placeholderColor;
});
_placeholderColor = placeholderColor;
self.placeholderView.textColor = placeholderColor;
}
/**
* 通過設置placeholder設置私有屬性placeholderView中的text
*/
- (void)setPlaceholder:(NSString *)placeholder {
_placeholder = placeholder;
self.placeholderView.text = placeholder;
}
/**
* 通過設置attributedPlaceHolder設置私有屬性placeholderView中的attributedText
*/
- (void)setAttributedPlaceHolder:(NSAttributedString *)attributedPlaceHolder {
_attributedPlaceHolder = attributedPlaceHolder;
self.placeholderView.attributedText = attributedPlaceHolder;
}
/**
* 通過設置_placeholderFont設置私有屬性placeholderView中的Font
*/
- (void)setPlaceholderFont:(UIFont *)placeholderFont {
_placeholderFont = placeholderFont;
self.placeholderView.font = placeholderFont;
if (self.font && _placeholderFont) {
}
}
- (void)setFont:(UIFont *)font {
[super setFont:font];
self.placeholderView.frame = CGRectMake(7, 8, self.bounds.size.width, font.lineHeight);
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setup];
}
return self;
}
- (void)setup {
self.scrollEnabled = NO;
self.scrollsToTop = NO;
self.showsHorizontalScrollIndicator = NO;
self.enablesReturnKeyAutomatically = YES;
self.layer.borderWidth = 1;
self.layer.borderColor = [UIColor lightGrayColor].CGColor;
_textViewSettingHeight = self.frame.size.height;
//實時監聽textView值得改變
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBeginEditing) name:UITextViewTextDidBeginEditingNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEndEditing) name:UITextViewTextDidEndEditingNotification object:self];
}
- (void)textDidChange {
NSInteger wordCount = self.text.length;
// NSLog(@"%ld",(long)wordCount);
if (_maxLengthOfText && wordCount >= _maxLengthOfText) {
self.text = [self.text substringToIndex:_maxLengthOfText];
if (_textOverLimitBlock) {
_textOverLimitBlock(_maxLengthOfText);
}
}
// 根據文字內容決定placeholderView是否隱藏
self.placeholderView.hidden = self.hasText;
NSInteger height = ceilf([self sizeThatFits:CGSizeMake(self.bounds.size.width, MAXFLOAT)].height);
if (_textH != height) { // 高度不一樣,就改變了高度
// 當高度大於最大高度時,需要滾動
self.scrollEnabled = height > _maxTextH && _maxTextH > 0;
_textH = height;
//當不可以滾動(即 <= 最大高度)時,傳值改變textView高度
if (_textChangedBlock && self.scrollEnabled == NO && height > _textViewSettingHeight) {
_textChangedBlock(self.text,height);
[self.superview layoutIfNeeded];
// self.placeholderView.frame = self.bounds;
}
}
}
- (void)didBeginEditing {
if (_placeholderHighLightColor) {
self.placeholderColor = _placeholderHighLightColor;
}else {
self.placeholderColor = [UIColor lightGrayColor];
}
}
- (void)didEndEditing {
self.placeholderColor = NormalColor;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)textValueDidChanged:(KP_textHeightChangedBlock)block {
_textChangedBlock = block;
}
- (void)textLengthOverLimit:(KP_textViewLengthOverLimitBlock)block {
_textOverLimitBlock = block;
}
- (CGRect)caretRectForPosition:(UITextPosition *)position
{
CGRect originalRect = [super caretRectForPosition:position];
if (_cursorHeight) {
originalRect.size.height = _cursorHeight;
}else {
originalRect.size.height = self.font.lineHeight + 4;
}
if (_cursorWidth) {
originalRect.size.width = _cursorWidth;
}else {
originalRect.size.width = 2;
}
return originalRect;
}
@end