管理文本字段和文本視圖 <- iOS文本編程指南

文本字段和文本視圖有兩個(gè)主要的功能:顯示文本宙搬,以及允許輸入和編輯文本饶碘。 很多編程任務(wù)和這些簡單的目標(biāo)相關(guān)聯(lián)目尖,包括配置文本對(duì)象、訪問當(dāng)前文本扎运、檢查用戶的輸入瑟曲、以及顯示覆蓋視圖(例如在文本字段中的書簽按鈕)。

UITextField或者UITextView對(duì)象的委托負(fù)責(zé)處理其中大部分的任務(wù)豪治。這些委托必須采用UITextFieldDelegate或者UITextViewDelegate協(xié)議洞拨,并使其中一個(gè)或多個(gè)方法。所有協(xié)議方法都是可選實(shí)現(xiàn)的负拟。為了能夠調(diào)用這些方法烦衣,你必須用編碼的方式或者Interface Builder設(shè)置文本字段和文本視圖的delegate屬性。

給委托發(fā)送的消息的順序

在大多數(shù)情況下齿椅,UITextField或UITextView類的實(shí)例會(huì)在給定的文本對(duì)象的第一響應(yīng)者狀態(tài)改變的時(shí)候發(fā)送一系列名字類似的信息給它們的委托琉挖。當(dāng)用戶點(diǎn)擊一個(gè)文本對(duì)象启泣,它會(huì)自動(dòng)變成第一響應(yīng)者涣脚;所以系統(tǒng)回味該文本對(duì)象顯示鍵盤并開始一個(gè)編輯會(huì)話。當(dāng)用戶點(diǎn)擊另一個(gè)文本對(duì)象或點(diǎn)擊按鈕來結(jié)束編輯的時(shí)候寥茫,當(dāng)前的文本對(duì)象注銷第一響應(yīng)者狀態(tài)遣蚀。如果沒有其他文本對(duì)象被選擇,系統(tǒng)會(huì)隱藏鍵盤纱耻;另一方面芭梯,如果用戶選擇了另一個(gè)文本對(duì)象,它會(huì)變成第一響應(yīng)者弄喘,并且鍵盤會(huì)為該對(duì)象而存在玖喘。

對(duì)于一般的行為有兩個(gè)例外。在iPad上蘑志,如果視圖控制器使用“form sheet”樣式模態(tài)呈現(xiàn)它的視圖累奈,顯示的鍵盤不會(huì)消失贬派,直到用戶點(diǎn)擊關(guān)閉按鈕或者模態(tài)視圖控制器以編程的方式關(guān)閉。這樣設(shè)計(jì)的目的是避免過多的動(dòng)畫澎媒。另一個(gè)例外是自定義輸入視圖搞乏。輸入視圖可以替代分配給文本視圖或自定義視圖的inputView屬性的系統(tǒng)鍵盤。當(dāng)有輸入視圖的時(shí)候戒努,即使文本對(duì)象是第一響應(yīng)者请敦,UIKit也可以切換鍵盤。

文本視圖和文本字段給它們委托發(fā)送信息的順序如下:

  1. 在文本對(duì)象剛剛成為第一響應(yīng)者之前——textFieldShouldBeginEditing: (文本字段) 和textViewShouldBeginEditing: (文本視圖)储玫。委托可以通過返回YES(默認(rèn))或NO來校驗(yàn)是否將文本對(duì)象變成第一響應(yīng)者侍筛。
  2. 在文本對(duì)象剛剛成為第一響應(yīng)者之后——textFieldDidBeginEditing: (文本字段) 和 textViewDidBeginEditing: (文本視圖)。委托可以通過諸如更新狀態(tài)信息或在編輯會(huì)話期間展示覆蓋視圖對(duì)該消息作出響應(yīng)撒穷。
  3. 在編輯會(huì)話期間——當(dāng)用戶輸入以及編輯文本的時(shí)候勾笆,文本對(duì)象調(diào)用合適的委托方法(如果實(shí)現(xiàn))。例如桥滨,文本視圖可以在文本改變時(shí)候窝爪,它的委托可以接受textViewDidChange:消息。文本字段可以在用于點(diǎn)擊它的清除按鈕的時(shí)候接受textFieldShouldClear: 消息齐媒;委托返回布爾值來說明是否清除文本蒲每。
    實(shí)現(xiàn)這些方法是為了輸入文本的有效性。例如喻括,如果文本應(yīng)該遵循給定的格式邀杏,那么在字符串未遵守格式的時(shí)候委托應(yīng)該返回NO。
  4. 在文本對(duì)象剛剛注銷第一響應(yīng)者之前——textFieldShouldEndEditing: (文本字段) 和 textViewShouldEndEditing: (文本視圖)唬血。實(shí)現(xiàn)這些方法的主要原因是望蜡,驗(yàn)證輸入的文本。例如拷恨,如果文本應(yīng)該符合給定的模式脖律,如果輸入的字符串不符合給定的模式,該委托會(huì)返回NO腕侄。默認(rèn)情況下返回的是YES小泉。
    相關(guān)的文本字段的方法是textFieldShouldReturn:。當(dāng)用戶點(diǎn)擊回車鍵的時(shí)候冕杠,文本字段會(huì)發(fā)送textFieldShouldReturn:方法給委托微姊,來詢問它是否應(yīng)該注銷第一響應(yīng)者。
  5. 在文本對(duì)象剛剛注銷第一響應(yīng)著之后————textFieldDidEndEditing: (文本字段) 和 textViewDidEndEditing: (文本視圖)分预。委托可以實(shí)現(xiàn)這些方法來獲取用戶剛剛輸入或編輯的文本兢交。

文本視圖和文本字段的第一響應(yīng)者狀態(tài)的改變,可以通過觀察通知來通知委托以外的對(duì)象笼痹。(但是配喳,它們不能批準(zhǔn)或拒絕新狀態(tài)的過渡飘诗。)通知有名字,例如UITextFieldTextDidBeginEditingNotification, UITextViewTextDidEndEditingNotification, 和 UITextViewTextDidChangeNotification界逛。和textFieldDidEndEditing: 和 textViewDidEndEditing:一樣昆稿,觀察并處理UITextFieldTextDidEndEditingNotification 和 UITextViewTextDidEndEditingNotification通知是為了訪問相關(guān)的文本字段和文本視圖。更多關(guān)于通過這些類發(fā)送的通知的信息息拜,參見UITextField Class Reference 和 UITextView Class Reference 溉潭。

配置文本字段和文本視圖

就像所有由UIKit框架提供的視圖對(duì)象一樣,你通常需要在文本字段和文本視圖顯示之前配置它們少欺。你可以用編程方式配置它們喳瓣,也可以使用在Interface Builder中的屬性檢查器來配置它們。這兩種方式赞别,你都是在設(shè)置文本對(duì)象的屬性畏陕。

有一些屬性對(duì)于文本視圖和文本對(duì)象是常見的,但是也有一些屬性對(duì)于每個(gè)類型的對(duì)象都是特定的仿滔,包括以下幾個(gè):

  • 文本特性——文本顏色惠毁、對(duì)齊方式、字體族崎页、字體鞠绰、以及字體尺寸。
  • 鍵盤——鍵盤類型飒焦、返回鍵名字蜈膨、安全文本輸入、以及自動(dòng)啟用的返回鍵牺荠,所有這些都通過UITextInputTraits協(xié)議聲明翁巍。(注意,與文本視圖相關(guān)聯(lián)的自動(dòng)啟用會(huì)車鍵休雌,在點(diǎn)擊時(shí)灶壶,它的行為和回車鍵一樣。)更多信息挑辆,參見“為文本對(duì)象配置鍵盤”例朱。
  • 文本字段特有——邊框孝情、背景圖片鱼蝉、禁用圖片、清除按鈕箫荡、以及展位文本魁亦。作為一個(gè)UIControl對(duì)象,文本字段也可以有高亮羔挡、選擇洁奈、啟用间唉、和其他屬性。
  • 文本視圖特有——可編輯狀態(tài)利术、數(shù)據(jù)探測(cè)器(針對(duì)電話號(hào)碼和URL連接)呈野。因?yàn)槲谋疽晥D繼承自UIScrollView,你可以通過設(shè)置合適的屬性個(gè)來管理滾動(dòng)視圖的行為印叁。

跟蹤多個(gè)文本字段或文本視圖

所有的UITextFieldDelegate或UITextViewDelegate協(xié)議的方法被冒,都有一個(gè)屬性來識(shí)別文本字段或文本視圖第一響應(yīng)者狀態(tài)的改變、值的改變轮蜕、或者其他委托信息原因的改變昨悼。如果只有一個(gè)文本對(duì)象在當(dāng)前的視圖中顯示,該文本對(duì)象通過上面的屬性進(jìn)行驗(yàn)證跃洛。但是率触,如果當(dāng)前視圖上面有多個(gè)文本字段或者文本視圖,委托必須找到某種方式來指示該文本對(duì)象就是委托信息的對(duì)象汇竭。

你可以使用以下兩種方法來確定:outlet或tag葱蝗。對(duì)于outlet方法,聲明一個(gè)outlet實(shí)例變量 (使用IBOutlet關(guān)鍵字)细燎,并建立一個(gè)outlet連接垒玲。在你的委托方法中,使用指針對(duì)照找颓,測(cè)試傳入的文本對(duì)象是否與outlet指示的對(duì)象相同合愈。例如,假設(shè)你聲明并連接了一個(gè)名為SSN的outlet击狮。你的代碼應(yīng)該和代碼清單3-1類似佛析。

代碼清單 3-1 使用outlet識(shí)別傳入的文本對(duì)象

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {

    if (textField == SSN) {

            // .....

            return NO;

        }

    return YES;

}

當(dāng)你需要將字符串值寫入到文本對(duì)象中,而不僅僅是獲取它們彪蓬,那么為在視圖中的這些文本對(duì)象定義outlet連接特別有用寸莫,甚至是必要的。

而對(duì)于tag方式档冬,聲明一組枚舉常量膘茎,每個(gè)tag對(duì)應(yīng)一個(gè)常量。

enum {

    NameFieldTag = 0,

    EmailFieldTag,

    DOBFieldTag,

    SSNFieldTag

};

然后通過編程方式或者Interface Builder方式把整型值分配給文本對(duì)象的tag屬性酷誓。(tag屬性在UIView中聲明了披坏。)在委托方法中,你可以使用seitch語句來評(píng)估傳入的文本對(duì)象的tag值盐数,從而繼續(xù)(如代碼清單3-2所示)棒拂。

文本清單 3-2 使用tag識(shí)別傳入的文本對(duì)象

- (void)textFieldDidEndEditing:(UITextField *)textField {

 

    switch (textField.tag) {

        case NameFieldTag:

            // do something with this text field

            break;

        case EmailFieldTag:

             // do something with this text field

            break;

        // remainder of switch statement....

    }

}

獲取輸入的文本并設(shè)置文本

在用戶在文本字段或文本視圖中輸入或者編輯文本且編輯會(huì)話結(jié)束之后,委托將獲得文本,并把它存儲(chǔ)在應(yīng)用的數(shù)據(jù)模型中帚屉。對(duì)于訪問輸入文本的最好的委托方法是textFieldDidEndEditing: (文本字段) 和 textViewDidEndEditing: (文本視圖).

代碼清單 3-3 演示了如何獲取用戶在文本字段中(使用tag值來在視圖中區(qū)別多個(gè)文本字段)輸入的文本谜诫。UITextField或者UITextView的text屬性通過文本對(duì)象持后當(dāng)前顯示的字符串。委托從該屬性中獲取字符串攻旦,并把它存儲(chǔ)在一個(gè)字典對(duì)象中喻旷。如果該文本字段換沒有字符串值(就是該字段持有一個(gè)空字符串),該委托就簡單的返回牢屋。

代碼清單 3-3 在文本字段中獲取輸入的文本

- (void)textFieldDidEndEditing:(UITextField *)textField {

    if ([textField.text isEqualToString:@""])

        return;

 

    switch (textField.tag) {

        case NameFieldTag:

            [thePerson setObject:textField.text forKey:MyAppPersonNameKey];

            break;

        case EmailFieldTag:

            [thePerson setObject:textField.text forKey:MyAppPersonEmailKey];

            break;

        case SSNFieldTag:

            [thePerson setObject:textField.text forKey:MyAppPersonSSNKey];

            break;

        default:

            break;

    }

}

代碼清單 3-4 顯示了textViewDidEndEditing: 方法的實(shí)現(xiàn)掰邢,它從文本視圖中獲取顯示的字符串,并把它存儲(chǔ)在字典中伟阔。這個(gè)方法不要求文本視圖注冊(cè)為第一響應(yīng)者辣之。(resignFirstResponder方法在動(dòng)作方法被調(diào)用之前被調(diào)用,該動(dòng)作方法在用戶在視圖的用戶界面上點(diǎn)擊完成按鈕的時(shí)候被調(diào)用皱炉。)

代碼清單 3-4 在文本視圖中獲取輸入的文本

- (void)textViewDidEndEditing:(UITextView *)textView {

    NSString *theText = textView.text;

    if (![theText isEqualToString:@""]) {

        [thePerson setObject:theText forKey:MyAppPersonNotesKey];

    }

    doneButton.enabled = NO;

}

如果你需要把字符串值寫入文本對(duì)象(通常在從app的數(shù)據(jù)模型檢索它們之后)怀估,只需要簡單的把字符串分配給文本對(duì)象的text屬性即可。例如:

NSString *storedValue = [thePerson objectForKey:MyAppPersonEmailKey];
emailField.text = storedValue;

為此,給想要寫入字符串的文本字段換或者文本視圖(在這個(gè)例子中時(shí)emailField)定義outlet是有用的。

在文本字段使用格式化器

格式化器對(duì)象自動(dòng)解析在特定格式中的字符串帅掘,并且將該字符串轉(zhuǎn)換成代表數(shù)字、日期康铭、或其他值的對(duì)象;它們還可以反操作赌髓,把NSData从藤、NSNumber、以及類似的對(duì)象轉(zhuǎn)換為代表這些對(duì)象值的格式化字符串锁蠕。Foundation框架提供抽象基礎(chǔ)類NSFormatter和兩個(gè)具體子類NSDateFormatter和NSNumberFormatter夷野。始終這些類,用戶可以在文本字段輸入類似下面的值:

11/15/2010

-1,348.09

然后app可以使用formatter對(duì)象將字符串分別轉(zhuǎn)換為NSData對(duì)象和NSNumber對(duì)象荣倾。

下面的代碼清單悯搔,使用了日期格式化器對(duì)象來說明格式化器的使用。(當(dāng)然舌仍,你可以使用UIDatePicker對(duì)象來代替文本字段輸入日期妒貌,而附加日期格式化器的文本字段是另一個(gè)選項(xiàng)。)代碼清單3-5中的代碼铸豁,創(chuàng)建了一個(gè)NSDateFormatter對(duì)象灌曙,并且給它分配了一個(gè)實(shí)例變量。它配置這個(gè)日期格式化器來使用日期的“短樣式”推姻,但是在某種程度上可以響應(yīng)日歷平匈、區(qū)域、以及時(shí)區(qū)的改變藏古。它還把今天的日期分配給給定的格式作為占位字符串增炭,以便用戶在輸入日期的時(shí)候有一個(gè)可以遵照的模型。

代碼清單 3-5 配置日期格式化器

- (void)viewDidLoad {
[super viewDidLoad];
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setGeneratesCalendarDates:YES];
[dateFormatter setLocale:[NSLocale currentLocale]];
[dateFormatter setCalendar:[NSCalendar autoupdatingCurrentCalendar]];
[dateFormatter setTimeZone:[NSTimeZone defaultTimeZone]];
[dateFormatter setDateStyle:NSDateFormatterShortStyle]; // example: 4/13/10
DOB.placeholder = [NSString stringWithFormat:@"Example: %@", [dateFormatter stringFromDate:[NSDate date]]];
// code continues....
}

在你配置了日期格式化器之后拧晕,該委托可以調(diào)用格式化器的dateFromString:方法隙姿,來把輸入的日期字符串轉(zhuǎn)換為NSData對(duì)象。代碼清單3-6顯示了此過程厂捞。

代碼清單3-6 使用NSDateFormatter對(duì)象输玷,把日期字符串轉(zhuǎn)化為數(shù)據(jù)對(duì)象

- (void)textFieldDidEndEditing:(UITextField *)textField {
[textField resignFirstResponder];
if ([textField.text isEqualToString:@""])
return;
switch (textField.tag) {
case DOBField:
NSDate *theDate = [dateFormatter dateFromString:textField.text];;
if (theDate)
[inputData setObject:theDate forKey:MyAppPersonDOBKey];
break;
// more switch case code here...
default:
break;
}
}

使用了格式化器并不能保證輸入的字符串必定包含了有效值(例如,用戶可以輸入13作為格里高利日歷的月份值)靡馁。為了確保用戶輸入正確的值欲鹏,委托必須驗(yàn)證字符串,這部分在驗(yàn)證輸入文本中已經(jīng)解釋了臭墨。因?yàn)轵?yàn)證經(jīng)常要求已知的格式和有效值的范圍赔嚎,如果你想代碼清單3-5那樣配置日期格式化器,以便它對(duì)于不同的日歷和區(qū)域敏感胧弛,則無法肯定的知道該格式尤误。想要指定一個(gè)已知的日期格式,通過調(diào)用setDateFormat:來配置日期格式化器结缚,給它傳遞一個(gè)通過Unicode標(biāo)準(zhǔn)定義的格式模型损晤。

你還可以將上面演示的過程反過來:把數(shù)據(jù)對(duì)象轉(zhuǎn)換成通過調(diào)用NSDateFormatter的方法stringFromDate:生成的字符串,然后把該字符串分配給文本字段红竭、文本視圖或者標(biāo)簽的text屬性尤勋。

更多關(guān)于NSDateFormatter和NSNumberFormatter的信息,參見Data Formatting Guide茵宪。

驗(yàn)證輸入的文本

App有時(shí)候不能接收在文本字段和文本視圖中輸入的沒有驗(yàn)證的字符串斥黑。或許該字符串必須是某種格式眉厨,也或者該值必須在特定范圍之內(nèi)锌奴。驗(yàn)證輸入字符串最好的委托方法,對(duì)于文本字段來說是textFieldShouldEndEditing:憾股,對(duì)于文本視圖來說是textViewShouldEndEditing:鹿蜀。這些方法在文本字段或文本視圖注冊(cè)為第一響應(yīng)者之前調(diào)用。返回NO來防止這種情況的發(fā)生服球,因此文本對(duì)象依然是編輯的重點(diǎn)茴恰。如果輸入的字符串是無效的,你還應(yīng)該顯示警告來提醒用戶這個(gè)錯(cuò)誤斩熊。

代碼清單3-7使用正則表達(dá)式來驗(yàn)證在“社會(huì)保障號(hào)碼”字段中輸入的字符串是否符合特定的格式往枣。

代碼清單 3-7 實(shí)用正則表達(dá)式驗(yàn)證文本字段的字符串格式

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
if (textField == SSN) { // SSN is an outlet
NSString *regEx = @"[0-9]{3}-[0-9]{2}-[0-9]{4}";
NSRange r = [textField.text rangeOfString:regEx options:NSRegularExpressionSearch];
if (r.location == NSNotFound) {
UIAlertView *av = [[[UIAlertView alloc] initWithTitle:@"Entry Error"
message:@"Enter social security number in 'NNN-NN-NNNN' format"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
[av show];
return NO;
}
}
return YES;
}

在代碼清單3-8中,實(shí)現(xiàn)了textViewShouldEndEditing:方法,強(qiáng)制限制了在文本視圖中輸入的文本的字符數(shù)分冈。

代碼清單 3-8 驗(yàn)證文本視圖允許的字符串長度

- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
if (textView.text.length > 50) {
UIAlertView *av = [[[UIAlertView alloc] initWithTitle:@"Entry Error"
message:@"You must enter less than 50 characters." delegate:self cancelButtonTitle:@"OK"
otherButtonTitles:@"Clear", nil] autorelease];
[av show];
return NO;
}
return YES;
}

委托還可以通過實(shí)現(xiàn)textField:shouldChangeCharactersInRange:replacementString:方法圾另,來驗(yàn)證在文本字段中輸入的每個(gè)字符。代碼清單3-9中的代碼雕沉,驗(yàn)證了每個(gè)輸入的字符(字符串)代表一個(gè)數(shù)字集乔。(你可以通過給文本字段指定UIKeyboardTypeNumberPad鍵盤來實(shí)現(xiàn)相同的目標(biāo)。)

代碼清單 3-9 驗(yàn)證每個(gè)輸入的字符

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
if ([string isEqualToString:@""]) return YES;
if (textField.tag == SalaryFieldTag) {
unichar c = [string characterAtIndex:0];
if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:c]) {
return YES;
} else {
return NO;
}
}
return YES;
}

你可以實(shí)現(xiàn)textField:shouldChangeCharactersInRange:replacementString:方法坡椒,在用戶輸入文本的時(shí)候提供單詞的可能完整性和更正功能扰路。

在文本字段中使用覆蓋視圖

覆蓋視圖是一個(gè)插入到文本字段左側(cè)或右側(cè)的小視圖。作為控件倔叼,當(dāng)用戶點(diǎn)擊它們的時(shí)候汗唱,可以操作文本字段當(dāng)前的內(nèi)容。搜索和書簽是覆蓋視圖的兩種常見任務(wù)丈攒,但是其他也是可能的哩罪。覆蓋視圖可以使用文本字段中(部分)URL加載web瀏覽器:

想要實(shí)現(xiàn)覆蓋視圖,創(chuàng)建一個(gè)和文本字段高度尺寸匹配的視圖肥印,并給該視圖一個(gè)合適尺寸的圖片识椰。如果該視圖是一個(gè)按鈕或其他空間,請(qǐng)指定目標(biāo)對(duì)象深碱、動(dòng)作選擇器腹鹉、和觸發(fā)控件事件。通常來說敷硅,你希望在文本字段聚焦于編輯的時(shí)候出現(xiàn)覆蓋視圖功咒,所以把它分配給textFieldDidBeginEditing: 委托方法中的leftView 或者rightView屬性。在編輯會(huì)話期間(例如在用戶輸入文本之前绞蹦,或者用戶剛剛開始輸入文本之后)力奋,在覆蓋視圖出現(xiàn)的時(shí)候,你可以通過將UITextFieldViewMode常量分配給leftViewMode或rightViewMode屬性進(jìn)行控制幽七。代碼清單3-10演示了如何實(shí)現(xiàn)覆蓋視圖景殷。

代碼清單 3-10在文本字段中顯示覆蓋視圖。

- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField.tag == NameField && self.overlayButton) {
textField.leftView = self.overlayButton;
textField.leftViewMode = UITextFieldViewModeAlways;
}
}
@dynamic overlayButton;
- (UIButton *)overlayButton {
if (!overlayButton) {
overlayButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
UIImage *overlayImage = [UIImage imageNamed:@"bookmark.png"];
if (overlayImage) {
[overlayButton setImage:overlayImage forState:UIControlStateNormal];
[overlayButton addTarget:self action:@selector(bookmarkTapped:)
forControlEvents:UIControlEventTouchUpInside];
}
}
return overlayButton;
}

如果你想使用覆蓋視圖的空間澡屡,請(qǐng)確保實(shí)現(xiàn)了該動(dòng)作方法猿挚。

要想移除掉覆蓋視圖,只要在textFieldDidEndEditing:委托方法中驶鹉,將leftView或者rightView屬性簡單設(shè)置為nil即可绩蜻。參照代碼清單3-11。

代碼清單 3-11移除覆蓋視圖

- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField.tag == NameFieldTag) {
textField.leftView = nil;
}
// remainder of implementation....
}

跟蹤文本視圖中的所選部分

UITextViewDelegate中的方法textViewDidChangeSelection:讓你可以跟蹤用戶在文本視圖中所選擇部分的修改室埋。你可以實(shí)現(xiàn)方法來獲取選擇部分的子字符串办绝,并對(duì)它進(jìn)行操作伊约。代碼清單3-12 是一個(gè)怪誕的例子,它讓所選子字符串的字符都變成大寫孕蝉。

代碼清單 3-12 獲取選中的子字符串并更改它

- (void)textViewDidChangeSelection:(UITextView *)textView {
NSRange r = textView.selectedRange;
if (r.length == 0) {
return;
}
NSString *selText = [textView.text substringWithRange:r];
NSString *upString = [selText uppercaseString];
NSString *newString = [textView.text stringByReplacingCharactersInRange:r withString:upString];
textView.text = newString;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末屡律,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子昔驱,更是在濱河造成了極大的恐慌疹尾,老刑警劉巖上忍,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骤肛,死亡現(xiàn)場離奇詭異,居然都是意外死亡窍蓝,警方通過查閱死者的電腦和手機(jī)腋颠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吓笙,“玉大人淑玫,你說我怎么就攤上這事∶婢Γ” “怎么了絮蒿?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長叁鉴。 經(jīng)常有香客問我土涝,道長,這世上最難降的妖魔是什么幌墓? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任但壮,我火速辦了婚禮,結(jié)果婚禮上常侣,老公的妹妹穿的比我還像新娘蜡饵。我一直安慰自己,他們只是感情好胳施,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布溯祸。 她就那樣靜靜地躺著,像睡著了一般舞肆。 火紅的嫁衣襯著肌膚如雪焦辅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天胆绊,我揣著相機(jī)與錄音氨鹏,去河邊找鬼。 笑死压状,一個(gè)胖子當(dāng)著我的面吹牛仆抵,可吹牛的內(nèi)容都是我干的跟继。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼镣丑,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼舔糖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起莺匠,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤金吗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后趣竣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摇庙,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年遥缕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卫袒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡单匣,死狀恐怖夕凝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情户秤,我是刑警寧澤码秉,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站鸡号,受9級(jí)特大地震影響转砖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜膜蠢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一堪藐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挑围,春花似錦礁竞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蜘矢,卻和暖如春狂男,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背品腹。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國打工岖食, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舞吭。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓泡垃,卻偏偏與公主長得像析珊,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蔑穴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 翻譯自“Collection View Programming Guide for iOS” 0 關(guān)于iOS集合視...
    lakerszhy閱讀 3,878評(píng)論 1 22
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法忠寻,類相關(guān)的語法,內(nèi)部類的語法存和,繼承相關(guān)的語法奕剃,異常的語法,線程的語...
    子非魚_t_閱讀 31,664評(píng)論 18 399
  • WorldTrotter 看起來不錯(cuò)捐腿,但到目前為止它并沒有做任何事情纵朋。 在本章中,您將向 WorldTrotter...
    titvax閱讀 686評(píng)論 0 0
  • 開悟之人不會(huì)把執(zhí)著心放在首位叙量;開悟之人是遍參法界倡蝙,就是在法界當(dāng)中到處去尋找更好的更適合自己的法門九串、戒律绞佩、怎么樣度人...
    定紅閱讀 201評(píng)論 0 0
  • 計(jì)劃吞金大鱷, 夢(mèng)中擁抱嫦娥猪钮。 休言夢(mèng)南柯品山, 不知國家政策。 法遏烤低,法遏肘交, 苦煞一群飛蛾。
    長安不肖生閱讀 259評(píng)論 0 3