[BS-19]更改UITextField的placeholder文字顏色的5種方法


更改UITextField的placeholder文字顏色的5種方法

 

想要達到的目標是:一個頁面上有多個UITextField,當用戶聚焦某textField時,該文本框的placeholder的文字會灰色變為白色,當文本框失去焦點時,placeholder顏色從白色再變回灰色。

 

1.放置UILabel

最簡單最笨的方法是在每個textField里放一個UILabel來充當placeholder,當該textField聚焦時,讓placeholder的文字會灰色變為白色,失焦后從白色再變回灰色。這種方法需要對每個UILabel和TextField拖線,通過監聽鍵盤通知或者UITextField的代理來獲悉textField是否聚焦,然后寫一堆if語句來判斷。

2.修改textField.attributedPlaceholder屬性

//通過NSAttributedString來更改placeholder顏色。此種方法比較麻煩的是,需要知道頁面上所有的textField什么時候聚焦,什么時候失焦(有兩種方法:A.監聽鍵盤彈出的通知  B.通過UITextField的代理方法textFieldDidBeginEditing),然后再判斷哪個是白色,哪個是灰色。如果頁面上textField非常多,就需要寫很多的if語句。

    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc]initWithString:@"手機號" attributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];

    self.phoneTextField.attributedPlaceholder = attrString;

3. 利用UITextField的子類重寫drawPlaceholderInRect:方法

   具體實現見代碼:

//該方法的好處是不用獲取Xib中textField的引用,不用拖線,直接將Xib中textField的class改為自定義類即可。以后有任何textField想要改變placeholder的顏色,直接定義為該類即可。但還是需要自己監控UITextField是否聚焦。

#import "WZCustomPlaceholderTextField.h"

@implementation WZCustomPlaceholderTextField
/**
 @interface NSString(NSStringDrawing)  NSString的分類
 - (CGSize)sizeWithAttributes:(nullable NSDictionary<NSString *, id> *)attrs NS_AVAILABLE(10_0, 7_0);
 - (void)drawAtPoint:(CGPoint)point withAttributes:(nullable NSDictionary<NSString *, id> *)attrs NS_AVAILABLE(10_0, 7_0);
 - (void)drawInRect:(CGRect)rect withAttributes:(nullable NSDictionary<NSString *, id> *)attrs NS_AVAILABLE(10_0, 7_0);
 @end
 */
- (void)drawPlaceholderInRect:(CGRect)rect {//rect代表該自定義textField的frame/rect
//因為placeholder屬於NSString類型,所有的NSString都有drawInRect方法,但此方法似乎只在draw開頭方法中有效
    [self.placeholder drawInRect:CGRectMake(0, 10, rect.size.width, rect.size.height) withAttributes:@{
                                                                                                       NSForegroundColorAttributeName:[UIColor whiteColor],
                                                                                                       NSFontAttributeName:[UIFont systemFontOfSize:15]
                                                                                                       }];
    
}


- (void)drawRect:(CGRect)rect {//rect代表該自定義textField的frame/rect
    [super drawRect:rect]; //調用父類UITextField的drawRect方法,將自定義尺寸傳進去。必須調用父類
  
}

@end

4.利用UITextField的子類重寫drawRect:方法,在drawRect中通過[self.placeholder drawInRect:]來進行設置。

5.通過KVC向UITextField隱藏的內部實例變量_placeholderLabel設值。

利用runtime打印出UITextField所有的實例變量,發現有個叫_placeholderLabel的內部實例變量,在自定義類中通過KVC設值。此方法好處是:利用KVC設值方便簡潔,而且可以寫在任何位置。本例中我們重寫becomeFirstResponder:和resignFirstResponder方法來監控UITextField是否聚焦,然后在其中利用KVC設值。

//  WZTextField.m

// 利用runtime打印出UITextField所有的實例變量,發現有個叫_placeholderLabel的內部實例變量,在自定義類中通過KVC設值。
//

#import "WZTextField.h"

@implementation WZTextField
//調用順序1 (從xib創建時調用)
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
    }
    return self;
}
//調用順序2 (從xib創建時調用)
- (void)awakeFromNib {

}

//調用順序3 (無論xib還是純代碼創建都會調用)
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    self.tintColor = self.textColor; //設置光標顏色和文字顏色一樣
}

- (BOOL)becomeFirstResponder {
    [self setValue:[UIColor whiteColor] forKeyPath:@"_placeholderLabel.textColor"];
    return [super becomeFirstResponder];
}

- (BOOL)resignFirstResponder {
    [self setValue:[UIColor grayColor] forKeyPath:@"_placeholderLabel.textColor"];
    return [super resignFirstResponder];
}

@end

 

 

 

 


免責聲明!

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



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