美文网首页
UITextView添加Placeholder

UITextView添加Placeholder

作者: 缺一门 | 来源:发表于2017-07-24 20:40 被阅读0次

    第一版本(并不能完美的适配8.0iOS手机)

    一开始采用kvc的方法,主要使用[self setValue:label forKey:@"_placeholderLabel"]对UITextView的私有属性进行赋值。

    //  UITextView+Extension.m
    //  UITextVIew-placeholder
    
    #import "UITextView+Extension.h"
    #import <objc/runtime.h>
    
    @implementation UITextView (Extension)
    
    + (void)load {
        
        // 获取类方法 class_getClassMethod
        // 获取对象方法 class_getInstanceMethod
        
        Method setFontMethod = class_getInstanceMethod(self, @selector(setFont:));
        Method was_setFontMethod = class_getInstanceMethod(self, @selector(was_setFont:));
        
        // 交换方法的实现
        method_exchangeImplementations(setFontMethod, was_setFontMethod);
    }
    
    - (void)was_setPlaceholderWithText:(NSString *)text Color:(UIColor *)color{
        //防止重复设置 cell复用等问题
        for (UIView *view in self.subviews) {
            if ([view isKindOfClass:[UILabel class]]) {
                [view removeFromSuperview];
            }
        }
    
        //设置占位label
        UILabel *label = [[UILabel alloc] init];
        label.text = text;
        label.font = self.font;
        label.textColor = color;
        
        [self addSubview:label];
        [self setValue:label forKey:@"_placeholderLabel"];
        
        //第一次会有位移
        self.text = @"1";
        self.text = @"";
    }
    
    - (void)was_setFont:(UIFont *)font{
        //调用原方法 setFont:
        [self was_setFont:font];
        //设置占位字符串的font
        UILabel *label = [self valueForKey:@"_placeholderLabel"];
        label.font = font;
        NSLog(@"%s", __func__);
    }
    @end
    
    

    之后在bugly上发现报错:

    设备机型
    iPhone 6 Plus

    系统版本
    8.1.3 (12B466)

    崩溃内容:
    [<UITextView 0x12d165200> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key _placeholderLabel.
    LilyForParent -[UITextView(Extension) was_setPlaceholderWithText:Color:] (UITextView+Extension.m:)
    bugly显示有错误日志,并不是iOS8.0以上系统都支持,不能找到
    _placeholderLabel这个关键字,所以感觉KVC不能使用,也不知道是不是其他的原因。

    改进型

    思路

    通过runtime关联对象方法,关联一个私有Label变量,实现占位字符串的功能。

    使用方法交换将TextView的font与placeholderlabel的font绑定,同时变化大小。

    //
    //  UITextView+Placeholder.m
    
    #import "UITextView+Placeholder.h"
    #import <objc/runtime.h>
    
    static const char *kPlaceholderKey = "kPlaceholderKey";
    static const char *kPlaceholderLabelKey = "kPlaceholderLabelKey";
    
    @interface UITextView (PlaceholderLabel)<UITextViewDelegate>
    
    @property (nonatomic, strong) UILabel *placeholderLabel;
    
    @end
    
    @implementation UITextView (Placeholder)
    
    + (void)load {
        
        // 获取类方法 class_getClassMethod
        // 获取对象方法 class_getInstanceMethod
        
        Method setFontMethod = class_getInstanceMethod(self, @selector(setFont:));
        Method was_setFontMethod = class_getInstanceMethod(self, @selector(was_setFont:));
        
        // 交换方法的实现
        method_exchangeImplementations(setFontMethod, was_setFontMethod);
    }
    
    - (void)was_setFont:(UIFont *)font{
        //调用原方法 setFont:
        [self was_setFont:font];
        //设置占位字符串的font
        if (self.placeholderLabel != nil) {
            self.placeholderLabel.font = font;
            NSLog(@"%s", __func__);
        }
    }
    
    - (UILabel *)placeholderLabel{
        return objc_getAssociatedObject(self, kPlaceholderLabelKey);
    }
    
    - (void)setPlaceholderLabel:(UILabel *)placeholderLabel{
        objc_setAssociatedObject(self, kPlaceholderLabelKey, placeholderLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSString *)placeholder{
        return objc_getAssociatedObject(self, kPlaceholderKey);
    }
    
    - (void)was_setPlaceholderWithText:(NSString *)placeholder Color:(UIColor *)color{
        objc_setAssociatedObject(self, kPlaceholderKey, placeholder, OBJC_ASSOCIATION_COPY_NONATOMIC);
        
        UILabel *label = [[UILabel alloc] init];
        label.text = placeholder;
        label.textColor = color;
        label.numberOfLines = 0;
        [label sizeToFit];
        [self addSubview:label];
        
        self.placeholderLabel = label;
        
        self.delegate = self;
    }
    
    - (void)layoutSubviews{
        [super layoutSubviews];
        //5  7.75是实验后得出的完美位置,如有需求可以修改
        self.placeholderLabel.frame = CGRectMake(5, 7.75, self.frame.size.width, self.frame.size.height);
        [self.placeholderLabel sizeToFit];
    }
    
    - (void)textViewDidChange:(UITextView *)textView{
        self.placeholderLabel.hidden = !(self.text.length == 0);
    }
    
    @end
    

    使用方法

    直接将UITextView+Placeholder.h和UITextView+Placeholder.m拖入项目中,在需要使用TextView的控制器内导入,调用下面方法可以

    - (void)was_setPlaceholderWithText:(NSString *)placeholder Color:(UIColor *)color;
    

    Thank you for your reading !

    Github:Demo

    相关文章

      网友评论

          本文标题:UITextView添加Placeholder

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