UITextView输入自适应行高

该博客介绍了如何创建一个自定义输入视图`CustomInputView`,该视图继承自`UITextView`并实现了输入文字时行高的自动适应。它包含占位符属性、最大行数限制、文字高度改变回调等功能,同时解决了输入时的滚动问题和占位符显示。示例代码展示了如何使用这个自定义视图,并动态调整相关组件的布局。

#import <UIKit/UIKit.h>


typedef void(^CM_textHeightChangedBlock)(NSString *text,CGFloat textHeight);



@interface CustomInputView : UITextView


/**

 *  占位文字

 */

@property (nonatomic,strong) NSString *placeholder;


/**

 *  占位文字颜色

 */

@property (nonatomic,strong) UIColor *placeholderColor;


/**

 *  占位符字体大小

 */

@property (nonatomic,strong)UIFont *placeholderFont;


/**

 *  textView最大行数

 */

@property (nonatomic,assign) NSUInteger maxNumberOfLines;


/**

 *  文字高度改变block → 文字高度改变会自动调用

 *  block参数(text) → 文字内容

 *  block参数(textHeight) → 文字高度

 */

@property (nonatomic,strong) CM_textHeightChangedBlock textChangedBlock;

/**

 *  设置圆角

 */

@property (nonatomic,assign) NSUInteger cornerRadius;


- (void)textValueDidChanged:(CM_textHeightChangedBlock)block;


/**

 *  文字高度

 */

@property (nonatomic,assign) NSInteger textH;


@end




#import "CustomInputView.h"


@interface CustomInputView ()

/**

 *  UITextView作为placeholderView,使placeholderView等于UITextView的大小,字体重叠显示,方便快捷,解决占位符问题.

 */

@property (nonatomic,weak) UITextView *placeholderView;




/**

 *  文字最大高度

 */

@property (nonatomic,assign) NSInteger maxTextH;



@end


@implementation CustomInputView


- (void)textValueDidChanged:(CM_textHeightChangedBlock)block{

    

    _textChangedBlock = block;


}

- (UITextView *)placeholderView

{

    if (!_placeholderView ) {

        UITextView *placeholderView = [[UITextView alloc] initWithFrame:self.bounds];

        _placeholderView = placeholderView;

        //防止textView输入时跳动问题

        _placeholderView.scrollEnabled = NO;

        _placeholderView.showsHorizontalScrollIndicator =NO;

        _placeholderView.showsVerticalScrollIndicator =NO;

        _placeholderView.userInteractionEnabled =NO;

        _placeholderView.font =  self.font;

        _placeholderView.textColor = [UIColorlightGrayColor];

        _placeholderView.backgroundColor = [UIColor clearColor];

        [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)setCornerRadius:(NSUInteger)cornerRadius

{

    _cornerRadius = cornerRadius;

    self.layer.cornerRadius = cornerRadius;

}


/**

 *  通过设置placeholder设置私有属性placeholderView中的textColor

 */

- (void)setPlaceholderColor:(UIColor *)placeholderColor

{

    _placeholderColor = placeholderColor;

    

    self.placeholderView.textColor = placeholderColor;

}

/**

 *  通过设置placeholder设置私有属性placeholderView中的textColor

 */

- (void)setPlaceholder:(NSString *)placeholder

{

    _placeholder = placeholder;

    

    self.placeholderView.text = placeholder;

}

/**

 *  通过设置_placeholderFont设置私有属性placeholderView中的Font

*/

- (void)setPlaceholderFont:(UIFont *)placeholderFont {


    _placeholderFont = placeholderFont;

    

    self.placeholderView.font = placeholderFont;

}



- (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;

    //实时监听textView值得改变

    [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(textDidChange)name:UITextViewTextDidChangeNotificationobject:self];

}


- (void)textDidChange

{

    // 根据文字内容决定placeholderView是否隐藏

    self.placeholderView.hidden = self.text.length > 0;

    

    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) {

            _textChangedBlock(self.text,height);

            

            [self.superview layoutIfNeeded];

            self.placeholderView.frame = self.bounds;


        }

    }

}


- (void)dealloc

{

    [[NSNotificationCenterdefaultCenter] removeObserver:self];

}


@end







#import "ViewController.h"

#import "CustomInputView.h"


@interface ViewController ()<UITextViewDelegate>


@property (strong,nonatomic) IBOutletCustomInputView *inputView;

@property (weak, nonatomic) IBOutletUILabel *text;


@end


@implementation ViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    

  _inputView = [[CustomInputViewalloc]initWithFrame:CGRectMake(100,100, 200, 40)];


    _inputView.font = [UIFont systemFontOfSize:18];

    _inputView.placeholder = @"测试文字";


    _inputView.cornerRadius = 4;

    _inputView.placeholderColor = [UIColor redColor];

    //_inputView.placeholderFont = [UIFont systemFontOfSize:22];

    // 设置文本框最大行数

    [_inputView textValueDidChanged:^(NSString *text, CGFloat textHeight) {

        CGRect frame = _inputView.frame;

        frame.size.height = textHeight;

        _inputView.frame = frame;

    }];

    

    _inputView.maxNumberOfLines = 10;

    [self.viewaddSubview:_inputView];

    

    

    //实时监听textView值得改变,用于动态调整label约束

    [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(textDidChange)name:UITextViewTextDidChangeNotificationobject:self.inputView];

}


- (void)dealloc {

    self.inputView.delegate = nil;

    [[NSNotificationCenterdefaultCenter] removeObserver:self];

}


#pragma mark - 实时监听textView值得改变,用于动态调整label约束

- (void)textDidChange {

    CGRect frame = self.text.frame;

    frame.origin.y = self.inputView.frame.origin.y +self.inputView.textH + 20;

    self.text.frame = frame;

}


@end









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值