前言:IOS自帶的UITextView并沒有像UITextField自帶placeholder屬性,是以我們需要自己構造一個出來。
注:如果光标位置在中左,需要設定
self.automaticallyAdjustsScrollViewInsets = NO;
這個屬性,這樣子,光标位置就會在上左位置,出現這個問題是由于使用系統自帶的UINavigationController導緻的。
簡單的使用,示例代碼如下:
CGFloat textViewX = AdaptedHeight(15);
CGFloat textViewY = KHeight64 + AdaptedHeight(30);
CGFloat textViewH = (KScreenHeight - 2*textViewY)/3;
CGFloat textViewW = KScreenWidth - 2*textViewX;
IWTextView *textView = [[IWTextView alloc] initWithFrame:CGRectMake(textViewX, textViewY, textViewW, textViewH) placeHolder:@"說點什麼..." maxLimitLength:0];
//是否隐藏字數統計控件
textView.isHidecountLabel = YES;
textView.textViewEndEditingBlock = ^(NSString *textStr){
//結束編輯的時候調用
};
[self.view addSubview:textView];
自定義控件代碼
#import <UIKit/UIKit.h>
typedef void(^IWTextViewEndEditingBlock)(NSString *textStr);
@interface IWTextView : UIView
/**
初始化對象
@param frame frame
@param placeHolderStr 占位字元
@param maxLimitLength 最大長度限制
*/
- (id)initWithFrame:(CGRect)frame placeHolder:(NSString *)placeHolderStr maxLimitLength:(NSInteger)maxLimitLength;
//預設顯示
@property (nonatomic,assign) BOOL isHidecountLabel;
@property (nonatomic,copy) IWTextViewEndEditingBlock textViewEndEditingBlock;
@end
#import "IWTextView.h"
@interface IWTextView ()<UITextViewDelegate>
{
NSInteger _maxLimitLength;
}
@property (nonatomic,strong) UILabel *placeholderLabel;
@property (nonatomic,strong) UITextView *contentTextView;
@property (nonatomic,strong) UILabel *countLabel;
@end
@implementation IWTextView
- (instancetype)init
{
self = [super init];
if (self) {
self.backgroundColor = [UIColor whiteColor];
self.layer.borderWidth = KBorderWidth;
self.layer.borderColor = KGreyColor.CGColor;
self.layer.cornerRadius = 5;
self.layer.masksToBounds = YES;
}
return self;
}
- (id)initWithFrame:(CGRect)frame placeHolder:(NSString *)placeHolderStr maxLimitLength:(NSInteger)maxLimitLength
{
//1.初始化對象
IWTextView *textView = [self init];
textView.frame = frame;
_maxLimitLength = maxLimitLength;
//2.占位Label
CGFloat placeholderLabelX = 15;
CGFloat placeholderLabelY = 10;
CGFloat placeholderLabelW = textView.frame.size.width - 2*placeholderLabelX;
CGFloat placeholderLabelH = 20;
self.placeholderLabel.frame = CGRectMake(placeholderLabelX, placeholderLabelY, placeholderLabelW, placeholderLabelH);
self.placeholderLabel.text = placeHolderStr;
[textView addSubview:self.placeholderLabel];
//3.計算字數統計的寬高
NSString *countStr;
if (maxLimitLength == 0) {
countStr = @"無字數限制";
}else {
countStr = [NSString stringWithFormat:@"目前可輸入%ld字",(long)maxLimitLength];
}
CGRect countR = [countStr boundingRectWithSize:CGSizeMake(KScreenWidth*0.5, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:KFontCaption} context:nil];
CGFloat countLabelW = countR.size.width;
CGFloat countLabelH = countR.size.height;
//4.添加UITextView
CGFloat contentTextViewX = 10;
CGFloat contentTextViewY = 5;
CGFloat contentTextViewW = textView.frame.size.width - 2*contentTextViewX;
CGFloat contentTextViewH = textView.frame.size.height - 2*contentTextViewY - countLabelH;
self.contentTextView.frame = CGRectMake(contentTextViewX, contentTextViewY, contentTextViewW, contentTextViewH);
[textView insertSubview:self.contentTextView belowSubview:self.placeholderLabel];
//5.添加字數統計
CGFloat countLabelX = textView.frame.size.width - countLabelW - contentTextViewX;
CGFloat countLabelY = CGRectGetMaxY(self.contentTextView.frame) - contentTextViewY;
self.countLabel.frame = CGRectMake(countLabelX, countLabelY, countLabelW, countLabelH);
self.countLabel.text = countStr;
[textView addSubview:self.countLabel];
return textView;
}
- (UILabel *)placeholderLabel
{
if (!_placeholderLabel) {
_placeholderLabel = [[UILabel alloc] init];
_placeholderLabel.font = KFontContent;
_placeholderLabel.textColor = KGreyColor;
}
return _placeholderLabel;
}
- (UITextView *)contentTextView
{
if (!_contentTextView) {
_contentTextView = [[UITextView alloc] init];
_contentTextView.delegate = self;
_contentTextView.textColor = KGreyColor54;
_contentTextView.font = KFontContent;
}
return _contentTextView;
}
- (UILabel *)countLabel
{
if (!_countLabel) {
_countLabel = [[UILabel alloc] init];
_countLabel.font = KFontCaption;
_countLabel.textColor = KGoldColor;
_countLabel.textAlignment = NSTextAlignmentRight;
}
return _countLabel;
}
- (void)setIsHidecountLabel:(BOOL)isHidecountLabel
{
_isHidecountLabel = isHidecountLabel;
self.countLabel.hidden = _isHidecountLabel;
}
#pragma mark - UITextView代理
- (void)textViewDidChange:(UITextView *)textView
{
if (textView.text.length == 0 || textView.text == nil) {
self.placeholderLabel.hidden = NO;
_countLabel.text = [NSString stringWithFormat:@"目前可輸入%ld字",(long)_maxLimitLength];
}else{
self.placeholderLabel.hidden = YES;
if (_maxLimitLength != 0) {
NSString *toBeString = textView.text;
UITextInputMode *mode = textView.textInputMode;
NSString *lang = mode.primaryLanguage;
if ([lang isEqualToString:@"zh-Hans"]) {
UITextRange *selectedRange = [textView markedTextRange];
UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];
if (!position && toBeString.length > _maxLimitLength) {
textView.text = [toBeString substringToIndex:_maxLimitLength];
}
if (!position) {
NSInteger count = _maxLimitLength - textView.text.length;
_countLabel.text = [NSString stringWithFormat:@"目前可輸入%ld字",(long)count];
}
}else {
if (toBeString.length > _maxLimitLength) {
textView.text = [toBeString substringToIndex:_maxLimitLength];
}
NSInteger count = _maxLimitLength - textView.text.length;
_countLabel.text = [NSString stringWithFormat:@"目前可輸入%ld字",(long)count];
}
}
}
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
if (_textViewEndEditingBlock) {
_textViewEndEditingBlock(textView.text);
}
}
@end