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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM