zoukankan      html  css  js  c++  java
  • iOS开发小技巧--自定义带有占位文字的TextView(两种方式)

    自定义控件注意或框架注意:自己暴露在外面的属性,一定要重写setter,保证外界与内部的交互性

    一.方案一:通过drawRect:方法将文字画到textView中,监听文字改变用的是通知中心(代理也可以监听文字改变,但是这种方式就成了自己作为自己的代理了,不推荐这种方法)发出的消息

    UITextViewTextDidChangeNotification.自己监听通知.

    • 对外界提供两个属性

    • 内部实现
     1 #import "ChaosPlaceholdTextView.h"
     2 
     3 @implementation ChaosPlaceholdTextView
     4 
     5 - (instancetype)initWithFrame:(CGRect)frame
     6 {
     7     if (self = [super initWithFrame:frame]) {
     8         
     9         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextViewTextDidChangeNotification object:nil];
    10         
    11         // 外界文字颜色不设置,默认为灰色
    12         self.placeholdColor = [UIColor grayColor];
    13     }
    14     return self;
    15 }
    16 
    17 - (void)dealloc
    18 {
    19     [[NSNotificationCenter defaultCenter] removeObserver:self];
    20 }
    21 
    22 - (void)textChange
    23 {
    24     [self setNeedsDisplay];
    25 }
    26 
    27 // 调用drawRect时,会将之前的图像擦除掉,重新绘制
    28 - (void)drawRect:(CGRect)rect {
    29     
    30     if ([self hasText]) return;
    31     
    32     rect.origin.y += (64 + 7);
    33     rect.origin.x += 5;
    34     rect.size.width -= 2 * rect.origin.x;
    35     
    36     NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    37     attrs[NSForegroundColorAttributeName] = self.placeholdColor;
    38     attrs[NSFontAttributeName] = [UIFont systemFontOfSize:17];
    39     [self.placehold drawInRect:rect withAttributes:attrs];
    40 }
    41 
    42 // 设计框架需注意,给外界提供了属性后,一定重写出行的setter,这样既可以时时监听使用者对属性的更改,还可以跟好的与外界代码进行交互
    43 - (void)setPlacehold:(NSString *)placehold
    44 {
    45     _placehold = placehold;
    46     // 设置了站位文字后,需要重绘一遍
    47     [self setNeedsDisplay];
    48 }
    49 
    50 - (void)setPlaceholdColor:(UIColor *)placeholdColor
    51 {
    52     _placeholdColor = placeholdColor;
    53     [self setNeedsDisplay];
    54 }
    55 
    56 // 同时,也要考虑到
    57 - (void)setFont:(UIFont *)font
    58 {
    59     [super setFont:font];
    60     
    61     [self setNeedsDisplay];
    62 }
    63 
    64 - (void)setText:(NSString *)text
    65 {
    66     [super setText:text];
    67     
    68     [self setNeedsDisplay];
    69 }
    70 
    71 - (void)setAttributedText:(NSAttributedString *)attributedText
    72 {
    73     [super setAttributedText:attributedText];
    74     
    75     [self setNeedsDisplay];
    76 }
    77 
    78 @end
    • 缺点:由于是画上去的,当设置了textView的alwaysBounceHorizontal属性后,不能跟随着scrollView的滑动而滑动,如下图

    方案二:通过给TextView添加一个Label,也是通过监听文字改变的通知,修改label的hidden属性.

      1 #import "ChaosPlaceholdTextView.h"
      2 
      3 @interface ChaosPlaceholdTextView()
      4 /** 占位文字label */
      5 @property (nonatomic, weak) UILabel *placeholderLabel;
      6 @end
      7 
      8 @implementation ChaosPlaceholdTextView
      9 
     10 - (UILabel *)placeholderLabel
     11 {
     12     if (!_placeholderLabel) {
     13         // 添加一个用来显示占位文字的label
     14         UILabel *placeholderLabel = [[UILabel alloc] init];
     15         placeholderLabel.numberOfLines = 0;
     16         placeholderLabel.x = 4;
     17         placeholderLabel.y = 7;
     18         [self addSubview:placeholderLabel];
     19         _placeholderLabel = placeholderLabel;
     20     }
     21     return _placeholderLabel;
     22 }
     23 
     24 - (instancetype)initWithFrame:(CGRect)frame
     25 {
     26     if (self = [super initWithFrame:frame]) {
     27         // 垂直方向上永远有弹簧效果
     28         self.alwaysBounceVertical = YES;
     29         
     30         // 默认字体
     31         self.font = [UIFont systemFontOfSize:15];
     32         
     33         // 默认的占位文字颜色
     34         self.placeholderColor = [UIColor grayColor];
     35         
     36         // 监听文字改变
     37         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:nil];
     38     }
     39     return self;
     40 }
     41 
     42 - (void)dealloc
     43 {
     44     [[NSNotificationCenter defaultCenter] removeObserver:self];
     45 }
     46 
     47 /**
     48  * 监听文字改变
     49  */
     50 - (void)textDidChange
     51 {
     52     // 只要有文字, 就隐藏占位文字label
     53     self.placeholderLabel.hidden = self.hasText;
     54 }
     55 
     56 /**
     57  * 更新占位文字的尺寸
     58  */
     59 - (void)updatePlaceholderLabelSize
     60 {
     61     CGSize maxSize = CGSizeMake(ChaosScreenW - 2 * self.placeholderLabel.x, MAXFLOAT);
     62     self.placeholderLabel.size = [self.placeholder boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.font} context:nil].size;
     63 }
     64 
     65 #pragma mark - 重写setter
     66 - (void)setPlaceholderColor:(UIColor *)placeholderColor
     67 {
     68     _placeholderColor = placeholderColor;
     69     
     70     self.placeholderLabel.textColor = placeholderColor;
     71 }
     72 
     73 - (void)setPlaceholder:(NSString *)placeholder
     74 {
     75     _placeholder = [placeholder copy];
     76     
     77     self.placeholderLabel.text = placeholder;
     78     
     79     [self updatePlaceholderLabelSize];
     80 }
     81 
     82 - (void)setFont:(UIFont *)font
     83 {
     84     [super setFont:font];
     85     
     86     self.placeholderLabel.font = font;
     87     
     88     [self updatePlaceholderLabelSize];
     89 }
     90 
     91 - (void)setText:(NSString *)text
     92 {
     93     [super setText:text];
     94     
     95     [self textDidChange];
     96 }
     97 
     98 - (void)setAttributedText:(NSAttributedString *)attributedText
     99 {
    100     [super setAttributedText:attributedText];
    101     
    102     [self textDidChange];
    103 }
    104 
    105 @end

     

  • 相关阅读:
    jquery 的 ajax 在 非阻塞 时返回 XMLHttpRequest
    关于TransactionScope出错:“与基础事务管理器的通信失败”的解决方法总结
    未能正确加载“radlangsvc.package,radlangsvc.vs,version=10.0.0,culture=neutra
    跨域iframe高度自适应(兼容IE/FF/OP/Chrome)
    Windows8不联网直接安装.Net 3.5 Framework的方法
    ubuntu创建、删除文件及文件夹,强制清空回收站方法
    Ubuntu java 环境变量
    mysql 和mssql2016中的json字段相关操作
    Windows任务计划
    配置mysql远程访问
  • 原文地址:https://www.cnblogs.com/gchlcc/p/5542774.html
Copyright © 2011-2022 走看看