iOS SDK基礎(chǔ):UITextView和UITextViewDelegate
我們計(jì)劃創(chuàng)建UITextView,實(shí)現(xiàn)UITextViewDelegate協(xié)議方法,使用NSLog檢查該方法何時(shí)被調(diào)用。我們還會(huì)接觸到如何在TextView中限制字符的數(shù)量,以及如何使用return鍵隱藏keyboard。看看如何在你的app中實(shí)現(xiàn)這些功能。
第一步:創(chuàng)建一個(gè)新的Xcode項(xiàng)目
運(yùn)行Xcode,依次點(diǎn)擊File > New > Project,然后在左邊點(diǎn)擊iOS下面的"Application",右邊選中"Single View Application",然后點(diǎn)擊“next”。
接下來如圖中所示,在"Product Name"這一欄鍵入 "TextViewARC",并在Company Identifier中填入一個(gè)值,例如"com.companyName." 。在“Device Family”列表中選擇“iPhone”。不要勾 選 "Use Storyboards" 和 "Include Unit Tests" ,勾選 上"UseAutomatic Reference Counting" 。在點(diǎn)擊下一步之前,核 對(duì)"Use Automatic Reference Counting",然后點(diǎn)擊next,并選擇一個(gè)位置來存儲(chǔ)工程,然后點(diǎn)擊“create”.
第二步:創(chuàng)建UITextView
UITextView的創(chuàng)建可以通過純代碼或者使用 Interface Builder工具來完成,接下來我們主要介紹如何通過這兩種方法來創(chuàng)建一個(gè)UITextView。
通過代碼創(chuàng)建
點(diǎn)擊“ViewController.m”文件,然后輸入以下代碼:
- CGRect textViewFrame = CGRectMake(20.0f, 20.0f, 280.0f, 124.0f);
- UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame];
- textView.returnKeyType = UIReturnKeyDone;
- [self.view addSubview:textView];
這樣創(chuàng)建了一個(gè)UITextView對(duì)象,并且添加到ViewController視圖中。
使用Interface Builder
你可以在.xib文件中創(chuàng)建UITextView。在Xcode的"Navigator"面板中點(diǎn) 擊 .xib文件,在左側(cè)文檔大綱"Document Outline"中點(diǎn)擊"View"。在菜單中點(diǎn)擊 View > Utilities > 展示Object Library。移至Object library的底部左下角,找 到"Text View",點(diǎn)擊選中,拖放至text view,調(diào)整text view位置至頂端, 高度修改為125像素。
第三步:隱藏鍵盤
隱藏鍵盤的方法很多,下面我們給出的代碼僅是其中的一種方法。點(diǎn)擊“ViewController.m”文件,添加以下方法來實(shí)現(xiàn):
- - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
- NSLog(@"touchesBegan:withEvent:");
- [self.view endEditing:YES];
- [super touchesBegan:touches withEvent:event];
- }
第四步:Delegate Protocol Methods
簡(jiǎn)單說,一個(gè)委托協(xié)實(shí)現(xiàn)兩個(gè)對(duì)象之間的相互通信,在UITextViewDelegate方法中,當(dāng)特定事件發(fā)生時(shí),UITextView就可以傳遞協(xié)議, 比如text view開始編輯時(shí)。當(dāng)方法被傳遞時(shí),你就可以在協(xié)議中做自己的一些處理。以下例子演示下如何實(shí)現(xiàn)UITextView委托協(xié)議方法。
在實(shí)現(xiàn)delegate方法之前,為了將viewcontroller對(duì)象設(shè)置為uitextview的delegate,我們把textview的 delegate屬性設(shè)置為self。點(diǎn)擊“ViewController.m”文件,在viewDidLoad方法中,在 [self.view addSubview:textView];上面添加以下代碼:
- textView.delegate = self;
使用Interface Builder,點(diǎn)擊"ViewController.xib"文件,選擇text view,點(diǎn)擊 View > Utilities > Show Connections Inspector。 在 "Connections Inspector"中點(diǎn)擊"Outlets"來打開它。點(diǎn)擊頁面上"delegate"向?qū)γ娴膱A圈,然后單擊該圓圈并 將其拖至“File‘s Owner”,以在text view和viewcontroller之間建立好連接。然后點(diǎn)擊 “ViewController.h”,輸入以下代碼以遵循UITextViewDelegate protocol。
- @interface ViewController : UIViewController <UITextViewDelegate>
UITextView委托協(xié)議方法是可選的,也就是說使用UITextViewDelegate協(xié)議,但是不一定非得實(shí)現(xiàn)相關(guān)的協(xié)議方法。下邊是在它們上邊添加的方法。
- textViewShouldBeginEditing: and textViewDidBeginEditing:
點(diǎn)擊“ViewController.m”文件,添加以下代碼:
- - (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
- NSLog(@"textViewShouldBeginEditing:");
- return YES;
- }
- - (void)textViewDidBeginEditing:(UITextView *)textView {
- NSLog(@"textViewDidBeginEditing:");
- textView.backgroundColor = [UIColor greenColor];
- }
在text view獲得焦點(diǎn)之前會(huì)調(diào)用textViewShouldBeginEditing: 方法。當(dāng)text view獲得焦點(diǎn)之后,并且已經(jīng)是第 一響應(yīng)者(first responder),那么會(huì)調(diào)用textViewDidBeginEditing: 方法。當(dāng)text view獲得焦點(diǎn)時(shí)要想 做一些自己的處理,那么就在這里進(jìn)行。在
我們的示例中,當(dāng)text view獲得焦點(diǎn)時(shí),是把text view的背景色設(shè)置為綠色.
- textViewShouldEndEditing: and textViewDidEndEditing:
在之前的方法中加入以下代碼
- - (BOOL)textViewShouldEndEditing:(UITextView *)textView{
- NSLog(@"textViewShouldEndEditing:");
- textView.backgroundColor = [UIColor whiteColor];
- return YES;
- }
- - (void)textViewDidEndEditing:(UITextView *)textView{
- NSLog(@"textViewDidEndEditing:");
- }
當(dāng)text view失去焦點(diǎn)之前會(huì)調(diào)用textViewShouldEndEditing。在示例中,我們使用textViewShouldEndEditing:讓背景色返回最初的顏色。
- textView:shouldChangeCharactersInRange:replacementString
在之前的方法中加入以下代碼:
- - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
- NSCharacterSet *doneButtonCharacterSet = [NSCharacterSet newlineCharacterSet];
- NSRange replacementTextRange = [text rangeOfCharacterFromSet:doneButtonCharacterSet];
- NSUInteger location = replacementTextRange.location;
- if (textView.text.length + text.length > 140){
- if (location != NSNotFound){
- [textView resignFirstResponder];
- }
- return NO;
- }
- else if (location != NSNotFound){
- [textView resignFirstResponder];
- return NO;
- }
- return YES;
- }
每次用戶通過鍵盤輸入字符時(shí),在字符顯示在text view之 前,textView:shouldChangeCharactersInRange:replacementString方法會(huì)被調(diào)用。這個(gè)方法中可以 方便的定位測(cè)試用戶輸入的字符,并且限制用戶輸入特定的字符。在上面的代碼中,我使用done鍵來隱藏鍵盤:通過檢測(cè)看replacement文本中是否包含newLineCharacterSet任意的字符。
如果有一個(gè)字符是來自newLineCharacterSet的,那么說明done按鈕被按過了,因此應(yīng)該將鍵盤隱藏起來。另外,在用戶每次輸入內(nèi)容時(shí),還 檢測(cè)text view當(dāng)前文本內(nèi)容的長(zhǎng)度,如果大于140個(gè)字符,則返回NO,這樣text view就可以限制輸入140個(gè)字符了。
- textViewDidChangeSelection:
在之前的方法中加入以下代碼:
- - (void)textViewDidChangeSelection:(UITextView *)textView{
- NSLog(@"textViewDidChangeSelection:");
- }
只有當(dāng)用戶修改了text view中的內(nèi)容時(shí),textViewDidChange:方法才會(huì)被調(diào)用。在該方法中,可以對(duì)用戶修改了text view中 的內(nèi)容進(jìn)行驗(yàn)證,以滿足自己的一些實(shí)際需求。例如,這里有一個(gè)應(yīng)用場(chǎng)景:當(dāng)text view限制最多可以輸入140個(gè)字符時(shí),此時(shí),在用戶修改文本內(nèi)容 時(shí),你希望顯示出還可以輸入多少個(gè)字符。那么每次文本內(nèi)容被用戶修改的時(shí)候,更新并顯示一下剩余可輸入的字符個(gè)數(shù)即可。
- textViewDidChangeSelection:
在之前的方法中加入以下代碼:
- - (void)textViewDidChangeSelection:(UITextView *)textView{
- NSLog(@"textViewDidChangeSelection:");
- }
當(dāng)用戶選擇text view中的部分內(nèi)容,或者更改文本選擇的范圍,或者在text view中粘貼入文本時(shí),函數(shù)textViewDidChangeSelection:將會(huì)被調(diào)用。該方法一般不使用,不過在某些情況下,非常有用。
第五步:測(cè)試Text Views
點(diǎn)擊Product>Run,或者點(diǎn)擊左上角的"Run",然后打開console窗口,并在text view中做一些字符輸入,刪除操作。當(dāng)delegate方法被調(diào)用時(shí),NSLog會(huì)打印出相應(yīng)的字符串。
在模擬器上展示text view