美文网首页奔跑吧 iOS
工欲善其事,必先利其器系列之 UITextView+Catego

工欲善其事,必先利其器系列之 UITextView+Catego

作者: SmileFans | 来源:发表于2017-03-01 15:59 被阅读51次

    UITextView 也是较长用的控件之一,唯一问题就是没有占位符
    本文介绍:
    1、UITextView 添加占位符
    2、算textview输入情况下的字符数,解决实现限制字符数时,计算不准的问题

    直接上代码:

    UITextView+Category.h

    #import <UIKit/UIKit.h>
    #import <objc/runtime.h>
    
    @interface UITextView (Category)<UITextViewDelegate>
    
    @property (nonatomic, strong) UITextView *placeHolderTextView;
    /**
     *  @brief  占位符
     */
    - (void)add_PlaceHolder:(NSString *)placeHolder;
    
    /**
     *  @brief  当前选中的字符串范围
     *
     *  @return NSRange
     */
    - (NSRange)selectedRange;
    /**
     *  @brief  选中所有文字
     */
    - (void)selectAllText;
    /**
     *  @brief  选中指定范围的文字
     *
     *  @param range NSRange范围
     */
    - (void)setSelectedRange:(NSRange)range;
    
    // 用于计算textview输入情况下的字符数,解决实现限制字符数时,计算不准的问题
    - (NSInteger)getInputLengthWithText:(NSString *)text;
    
    

    UITextView+Category.m

    #import "UITextView+Category.h"
    
    static const char *phTextView = "placeHolderTextView";
    
    @implementation UITextView (Category)
    
    /**
     *  @brief  占位符
     */
    - (UITextView *)placeHolderTextView {
        return objc_getAssociatedObject(self, phTextView);
    }
    - (void)setPlaceHolderTextView:(UITextView *)placeHolderTextView {
        objc_setAssociatedObject(self, phTextView, placeHolderTextView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    - (void)add_PlaceHolder:(NSString *)placeHolder {
        if (![self placeHolderTextView]) {
            self.delegate = self;
            UITextView *textView = [[UITextView alloc] initWithFrame:self.bounds];
            textView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
            textView.font = self.font;
            textView.backgroundColor = [UIColor clearColor];
            textView.textColor = [UIColor grayColor];
            textView.userInteractionEnabled = NO;
            textView.text = placeHolder;
            [self addSubview:textView];
            [self setPlaceHolderTextView:textView];
        }
    }
    # pragma mark -
    # pragma mark - UITextViewDelegate
    - (void)textViewDidBeginEditing:(UITextView *)textView {
        self.placeHolderTextView.hidden = YES;
        // if (self.textViewDelegate) {
        //
        // }
    }
    - (void)textViewDidEndEditing:(UITextView *)textView {
        if (textView.text && [textView.text isEqualToString:@""]) {
            self.placeHolderTextView.hidden = NO;
        }
    }
    
    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
        NSInteger textLength = [textView getInputLengthWithText:text];
        if (textLength > 20) {
            // 超过20个字可以删除
            if ([text isEqualToString:@""]) {
                return YES;
            }
            return NO;
        }
        return YES;
    }
    
    - (void)textViewDidChange:(UITextView *)textView
    {
        if ([textView getInputLengthWithText:nil] > 20) {
            textView.text = [textView.text substringToIndex:20];
        }
    }
    
    
    /**
     *  @brief  当前选中的字符串范围
     *
     *  @return NSRange
     */
    - (NSRange)selectedRange
    {
        UITextPosition* beginning = self.beginningOfDocument;
        
        UITextRange* selectedRange = self.selectedTextRange;
        UITextPosition* selectionStart = selectedRange.start;
        UITextPosition* selectionEnd = selectedRange.end;
        
        NSInteger location = [self offsetFromPosition:beginning toPosition:selectionStart];
        NSInteger length = [self offsetFromPosition:selectionStart toPosition:selectionEnd];
        
        return NSMakeRange(location, length);
    }
    /**
     *  @brief  选中所有文字
     */
    - (void)selectAllText {
        UITextRange *range = [self textRangeFromPosition:self.beginningOfDocument toPosition:self.endOfDocument];
        [self setSelectedTextRange:range];
    }
    /**
     *  @brief  选中指定范围的文字
     *
     *  @param range NSRange范围
     */
    - (void)setSelectedRange:(NSRange)range {
        UITextPosition *beginning = self.beginningOfDocument;
        UITextPosition *startPosition = [self positionFromPosition:beginning offset:range.location];
        UITextPosition *endPosition = [self positionFromPosition:beginning offset:NSMaxRange(range)];
        UITextRange *selectionRange = [self textRangeFromPosition:startPosition toPosition:endPosition];
        [self setSelectedTextRange:selectionRange];
    }
    //https://github.com/pclion/TextViewCalculateLength
    // 用于计算textview输入情况下的字符数,解决实现限制字符数时,计算不准的问题
    
    - (NSInteger)getInputLengthWithText:(NSString *)text
    {
        NSInteger textLength = 0;
        //获取高亮部分
        UITextRange *selectedRange = [self markedTextRange];
        if (selectedRange) {
            NSString *newText = [self textInRange:selectedRange];
            textLength = (newText.length + 1) / 2 + [self offsetFromPosition:self.beginningOfDocument toPosition:selectedRange.start] + text.length;
        } else {
            textLength = self.text.length + text.length;
        }
        return textLength;
    }
    
    @end
    
    

    用法

        UITextView * textView =[[UITextView alloc]initWithFrame:CGRectMake(30, 100, KScreenWidth-60, 250)];
        textView.backgroundColor = [UIColor lightGrayColor];
        textView.font = [UIFont systemFontOfSize:18];
        [textView add_PlaceHolder:@"请输入内心独白(20字以内)~"];
        [self.view addSubview:textView];
    

    效果

    9E07218F-AB43-414E-9304-523644A4F575.png

    项目传送门
    项目地址
    https://github.com/SmileMee/SmileHelper.git


    我是写代码的凡,如有错误,欢迎指正!🙂🙂🙂

    相关文章

      网友评论

        本文标题:工欲善其事,必先利其器系列之 UITextView+Catego

        本文链接:https://www.haomeiwen.com/subject/ejxcgttx.html