用 RunTime 為 UITextView 設(shè)置占位文本并實時改變文本框占位文本的顏色

UITextView 實現(xiàn)占位文本的方式有很多種,網(wǎng)上一搜一大把,,這里只介紹 最簡單 的一種,如標(biāo)題所述:RunTimeUITextView 設(shè)置占位文本并實時改變文本框占位文本的顏色。

RunTime 不太了解的童鞋可以簡單看下這篇文章:iOS開發(fā)之 - Runtime,懶得點擊鼠標(biāo)的話我這里也簡單的說下,Runtime 簡稱運行時,是蘋果官方的一套比較底層的純 C 語言 API, 用它可以做很多底層操作(比如訪問隱藏的成員變量和方法)。

OK,足夠了,接下來我們就抓緊時間來看看如何用 RunTime 為 UITextView 設(shè)置占位文本并實時改變文本框占位文本的顏色。。。

首先我們利用 RunTime 獲取一下 UITextView 中一些隱藏的成員變量
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //  獲取 UITextView 中所有的成員變量
    unsigned int count = 0;
    Ivar *ivars = class_copyIvarList([UITextView class], &count);
    
    for (int i = 0; i < count; i ++) {
        Ivar ivar = ivars[i];
        // ivar_getName(ivar) 意思是獲取成員變量名字,如果想獲得成員變量的類型用這個 ivar_getTypeEncoding(ivar)
        const char *name = ivar_getName(ivar);
        NSString *objcName = [NSString stringWithUTF8String:name];
        
        NSLog(@"    %d     %@    ", i, objcName);
    }
    // 釋放
    free(ivars);
}
打印結(jié)果如下(這里直接放截圖)
UITextView 中的屬性

從上面的截圖中我們可以看出,打印的結(jié)果里有一個 placeHolderLabel 的私有變量,即 UITextView 類內(nèi)部有一個名為“_placeHolderLabel”的私有成員變量。那么就簡單多了,我們現(xiàn)在就對這個私有變量進(jìn)行操作。具體的步驟如下:

- (void)setupTextView {
    _textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 50, [UIScreen mainScreen].bounds.size.width, 200)];
    _textView.delegate = self;
    _textView.tintColor = [UIColor whiteColor];
    _textView.font = [UIFont systemFontOfSize:15.f];
    _textView.backgroundColor =[UIColor grayColor];
    [self.view addSubview:_textView];
    
    UILabel *placeholderLabel = [[UILabel alloc] init];
    placeholderLabel.text = @"請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容";
    placeholderLabel.font = [UIFont systemFontOfSize:15.f];
    placeholderLabel.textColor = [UIColor whiteColor];
    placeholderLabel.numberOfLines = 0;
    [placeholderLabel sizeToFit];
    [_textView addSubview:placeholderLabel];
    
    [_textView setValue:placeholderLabel forKey:@"_placeholderLabel"];
}

上面代碼做的事情,無非是創(chuàng)建一個 UITextView 和一個 UILabel 控件,然后通過鍵值對的原理給 UITextView 中的 _placeholderLabel 這一屬性賦值,,,就不詳細(xì)注釋了,重要的是這種思想。。。只需上面這段代碼,我們就已經(jīng)完成了利用 RunTime 為 UITextView 設(shè)置占位文本。效果圖如下,比較丑但很實用??:

為 UITextView 設(shè)置占位文本
接下來我們開始實時改變文本框占位文本的顏色。

舉個栗子:當(dāng)我們開始輸入時占位文本是白色,結(jié)束輸入時占位文本是灰色。那我們在哪里設(shè)置比較好呢?我在 UITextViewDelegate 中找到了兩個方法,可以解決我們的需求

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView;
- (BOOL)textViewShouldEndEditing:(UITextView *)textView;

看名字就能猜到這倆方法是干嘛的了,這里不再多說,,,我們需要在這兩個方法里進(jìn)行一些操作,先貼代碼。

#pragma mark - UITextViewDelegate
#pragma mark - 開始編輯 UITextView
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
    // 設(shè)置高亮?xí)r,占位文字顏色為白色
    [_textView setValue:[UIColor whiteColor] forKeyPath:@"_placeholderLabel.textColor"];
    // 設(shè)置光標(biāo)顏色為白色
    _textView.tintColor = [UIColor whiteColor];
    return YES;
}

#pragma mark - 結(jié)束編輯 UITextView
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
    
    // 設(shè)置非高亮狀態(tài)下,占位文字顏色為 lightGrayColor
    [_textView setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
    // 設(shè)置光標(biāo)顏色為 lightGrayColor
    _textView.tintColor = [UIColor lightGrayColor];
    return YES;
}

和上文設(shè)置占位文本的思想一樣,這里也是 根據(jù)鍵值對的原理給 _placeholderLabel.textColor 賦值,開始編輯時設(shè)置為白色,結(jié)束編輯時設(shè)置為 lightGrayColor,具體請看代碼中的注釋。

到這里實時改變文本框占位文本的顏色也搞定了,是不是覺得很簡單,先看下效果圖(比較丑但很使用??),文章結(jié)尾我會再次貼出完整的代碼。。。自己以后看著方便,也可以幫助有需要的道友少走彎路,,不過文章如果有需要改正或改進(jìn)的地方,還希望各位同行能多多指點。

效果圖
為 UITextView 設(shè)置占位文本并實時改變文本框占位文本的顏色


</br>

在需要 UITextView 的頁面進(jìn)行設(shè)置,NNViewController.h 中沒有相關(guān)操作,直接在NNViewController.m 中進(jìn)行設(shè)置即可,當(dāng)然如果項目中用到 UITextView 這個類比較多的話,你也可以簡單封裝一下,以便多次利用。。。以下是全部代碼
#import "NNViewController.h"
#import <objc/runtime.h>

@interface NNViewController ()<UITextViewDelegate> {
    UITextView *_textView;
}

@end

@implementation NNViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //  獲取 UITextView 中所有的成員變量
    unsigned int count = 0;
    Ivar *ivars = class_copyIvarList([UITextView class], &count);
    
    for (int i = 0; i < count; i ++) {
        Ivar ivar = ivars[i];
        // ivar_getName(ivar) 意思是獲取成員變量名字,如果想獲得成員變量的類型用這個 ivar_getTypeEncoding(ivar)
        const char *name = ivar_getName(ivar);
        NSString *objcName = [NSString stringWithUTF8String:name];
        
        NSLog(@"    %d     %@    ", i, objcName);
    }
    // 釋放
    free(ivars);
        [self setupTextView];
}


- (void)setupTextView {
    _textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 50, [UIScreen mainScreen].bounds.size.width, 200)];
    _textView.delegate = self;
    _textView.tintColor = [UIColor lightGrayColor];
    _textView.font = [UIFont systemFontOfSize:15.f];
    _textView.backgroundColor =[UIColor grayColor];
    [self.view addSubview:_textView];
    
    UILabel *placeholderLabel = [[UILabel alloc] init];
    placeholderLabel.text = @"請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容請輸入內(nèi)容";
    placeholderLabel.font = [UIFont systemFontOfSize:15.f];
    placeholderLabel.textColor = [UIColor lightGrayColor];
    placeholderLabel.numberOfLines = 0;
    [placeholderLabel sizeToFit];
    [_textView addSubview:placeholderLabel];
    
    [_textView setValue:placeholderLabel forKey:@"_placeholderLabel"];
}

#pragma mark - UITextViewDelegate
#pragma mark - 開始編輯 UITextView
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
    // 設(shè)置高亮?xí)r,占位文字顏色為白色
    [_textView setValue:[UIColor whiteColor] forKeyPath:@"_placeholderLabel.textColor"];
    // 設(shè)置光標(biāo)顏色為白色
    _textView.tintColor = [UIColor whiteColor];
    return YES;
}

#pragma mark - 結(jié)束編輯 UITextView
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
    
    // 設(shè)置非高亮狀態(tài)下,占位文字顏色為 lightGrayColor
    [_textView setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
    // 設(shè)置光標(biāo)顏色為 lightGrayColor
    _textView.tintColor = [UIColor lightGrayColor];
    return YES;
}

#pragma mark - 點擊空白頁面時收回鍵盤
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
}

@end


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容