天天看點

IOS 一個帶有placeholder的UITextView

前言: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