iOS Apprentice中文版-從0開始學iOS開發(fā)-第十五課

來個深加工

在你寫代碼將文本作為一條新的紀錄插入列表之前禽捆,讓我們先來改進一下新增待辦事項頁面的工作方式和設計琐凭。

例如:如果可以自動為用戶彈出鍵盤统屈,而不是當用戶點擊后才彈出鍵盤,這樣體驗會好一些吨掌。

為了達到這個目的窿侈,需要在AddItemViewController.swift中添加一個方法viewWillAppear():

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        textField.becomeFirstResponder()
    }

視圖控制器在即將可視化之前接收viewWillAppear()的消息,這正是激活文本框的完美時機。我們在這里發(fā)送becomeFirstResponder()消息衙傀。

如果你是在其他平臺上做這個事火本,通常被稱為“控制聚焦”茫陆。在iOS術(shù)語中簿盅,這種控制方法稱為“第一響應(first responder)”

運行app然后點擊?號按鈕现斋,你可以看到鍵盤會自動滑出來了瞬内。

(再說一次倦西,如果模擬器上鍵盤沒有自動滑出的話,可以通過command+K組合鍵喚醒鍵盤)

像這樣的小細節(jié)通常會帶來很好的用戶體驗。比起必須點擊文本框才能打字,現(xiàn)在的做法明顯快了不少。在這個日新月異的年代中,人們使用產(chǎn)品時不會有太多的耐心。比如一點點的瑕疵都會讓用戶轉(zhuǎn)移到你競爭對手的產(chǎn)品上去。我總是花大量的精力來使自己的app盡可能的完美。

所以,我們來繼續(xù)改進一下輸入框。

打開故事模版并且選定文本框俱病,進入到屬性檢查器并且按照下面的列表進行設置:

1、Placeholder:Name of the Item

2果元、Font:System 17

3倡怎、Adjust to Fit:Uncheck this

4贱枣、Capitalization:Sentence

5监署、Return Key:Done

設置文本框的屬性

這里有一些選項可以使你配置文本框被激活時的鍵盤的屬性。

例如纽哥,如果這個文本框僅可以輸入數(shù)值的話钠乏,你可以設置Keyboard Type為Number Pad。如果這是一個用于輸入Email地址的文本框春塌,你就可以將Keyboard Type為E-mail Address晓避。對我們這個app而言,默認的類型就正好符號要求只壳,因為用戶可以隨意輸入自己將要做的事情够滑。

你也可以改變鍵盤上回車鍵的名稱。默認的是“return”吕世,這里我們改為了“Done”。這只是按鈕上的標題文本梯投,點擊這個“Done”并不會自動關(guān)閉當前界面命辖,你還需要將鍵盤上的“Done”按鈕指向到相同的動作上,這樣鍵盤上的Done按鈕才能和導航欄上的Done按鈕起到相同的作用分蓖。

選定text field然后打開鏈接檢查器尔艇,拖拽Did End on Exit事件到視圖控制器,并且選擇done動作么鹤。

如果你的輔助編輯器還沒關(guān)的話终娃,也可以直接拖拽到源代碼的done()方法上。

鏈接text field到done()動作方法

查看done動作的鏈接可以點擊done()方法左邊蒸甜,屏幕邊緣上的那個小圓圈棠耕,點擊后會彈出一個窗口顯示done()方法的鏈接內(nèi)容。

運行app柠新,點擊鍵盤上的Done按鈕窍荧,這時界面會自動關(guān)閉,并且在調(diào)試區(qū)域打印出我們預置的文本信息恨憎。

現(xiàn)在鍵盤上的Done按鈕和導航欄上的Done按鈕作用一致了

驗證用戶的輸入并且確保它們被接收到了蕊退,是必不可缺的一個步驟。例如,用戶瞬間點了一下Done按鈕但是什么都沒輸入會發(fā)生什么瓤荔。

在主界面的列表中净蚤,新增一個空白的什么都沒有的行,可一點也不好输硝,為了避免這件事的發(fā)生你需要在用戶什么都沒有輸入前今瀑,禁止done按鈕的作用。

當然腔丧,你需要同時處理兩個done按鈕放椰,鍵盤上的一個,導航欄上的一個愉粤。讓我們先著手處理鍵盤上的done按鈕砾医,這個稍微簡單一些。

選中文本框衣厘,打開屬性檢查器如蚜,選中Auto-enable Return Key。

就這樣影暴,現(xiàn)在你運行app错邦,什么也不輸入,點擊鍵盤上的Done按鈕是不會起作用的型宙,試試看撬呢!

選中Auto-enable Return Key

對于導航欄上的Done按鈕,工作就復雜一些了妆兑。你需要監(jiān)聽每次一次用戶敲擊鍵盤后魂拦,文本框中的內(nèi)容是否為空。如果為空搁嗓,則禁用Done按鈕芯勘。

如果用戶的本身是點錯了,可以通過Cancel按鈕退出界面腺逛,但是用戶點擊Done按鈕時荷愕,必須保證文本框中有輸入的內(nèi)容。

對于文本框而言棍矛,有兩種輸入方法安疗,敲擊鍵盤輸入和復制黏貼,你需要給視圖控制器一個委托用于文本框茄靠。

當文本框發(fā)送事件到這個委托時茂契,你就可以知道文本框的情況了。這個委托存在于AdditemViewController內(nèi)慨绳,可以對文本框的事件進行響應掉冶,并且做出合適的動作真竖。

一個視圖控制器允許委托多個對象。AdditemViewController已經(jīng)有了一個委托和一個數(shù)據(jù)源用于UITableView厌小,因為它本來就是一個UITableViewController∩退郑現(xiàn)在它要增加一個委托用于text field的對象御雕,UITextfiled。

這是兩種不同類型的委托并且你要使視圖控制同時執(zhí)行它們的規(guī)則。關(guān)于委托的更多內(nèi)容我們會在下一個課程中講解勺三。

如何定義一個委托
在iOS系統(tǒng)的SDK里唇兑,委托無處不在辫狼,所以我們最好記住它總是由三個步驟完成聪蘸。
1、你申明自己有能力成為一個委托——成為UITextField的委托你需要將UITextFieldDelegate寫到視圖控制器的類的聲明中去疯搅。這樣就告訴了編譯器這個視圖控制器可以處理來自文本框的消息濒生。
2、你讓那個有問題的對象知道視圖控制器愿意成為它的委托——在我們這個例子里幔欧,這個對象是UITextField罪治。如果你忘記了告訴文本框它有一個委托,則這個文本框永遠不會發(fā)送任何消息礁蔗。
3觉义、執(zhí)行委托方法——如果你沒有對你發(fā)出的消息進行響應,那么委托根本不會成立浴井。
通常晒骇,委托方法是可選的,所以你不需要執(zhí)行全部的委托方法磺浙。例如:UITextFieldDelegate實際上聲明了七個方法但是你僅僅關(guān)心textField(shouldChangeCharactersIn, replacementString)這一個厉碟。

打開AddItemViewController.swift,添加UITextFieldDelegate到類的聲明中屠缭。

class AddItemViewController: UITableViewController,UITextFieldDelegate

現(xiàn)在視圖控制器好比在說:“我可以做為text filed對象的委托了”
你同時也需要讓text field知道這個委托的存在。

打開故事模版并且選定text field崭参。

這里有好幾種方法鏈接text field的委托outlet到視圖控制器呵曹。我比較喜歡從鏈接檢查器拖拽委托到視圖控制器(黃色圖標那個,見下圖):

從鏈接指示器拖拽文本框的委托到視圖控制器

你同時還需要添加一個outlet到導航欄的Done按鈕上何暮,如此你就可以從視圖控制器內(nèi)部向它發(fā)送消息奄喂,以達到禁用它的目的。

打開輔助編輯器海洼,并且確保輔助編輯界面展示的是AddItemViewController.swift跨新。

選定導航欄的Done按鈕并且按住ctrl拖拽它到輔助編輯窗口的swift文件中去,給這個新的outlet命名為doneBarButton坏逢。

這是swift文件中應該增加了這樣一行:

@IBOutlet weak var doneBarButton: UIBarButtonItem!

在AddItemViewController.swift的底部添加如下方法:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String)-> Bool {
        let oldText = textField.text! as NSString
        let newText = oldText.replacingCharacters(in: range, with: string) as NSString
        
        if newText.length > 0 {
            doneBarButton.isEnabled = true
        } else {
            doneBarButton.isEnabled = false
        }
        return true
    }

這是UITextField的委托方法之一域帐。每次用戶修改文本后它都會被調(diào)用赘被,無論是輸入還是黏貼復制。

首先肖揣,你判斷了新的文本內(nèi)容:

let oldText = textField.text! as NSString
        let newText = oldText.replacingCharacters(in: range, with: string) as NSString

委托方法textField(shouldChangeCharactersIn, replacementString)不能直接給出關(guān)于新文本的內(nèi)容民假,只有文本發(fā)生變更的時候才可以。

你需要通過讀取文本框的內(nèi)容來計算新的文本是什么龙优,并且用它自己替換自己羊异。這樣你才能得到一個新的字符串對象,并且將它存儲在newText常量中彤断。

NSString與String
文本字符串在swift中的數(shù)據(jù)類型為String野舶。但是在上面的方法中你使用了某種叫做NSString的東西。這兩者有什么區(qū)別呢宰衙?
NSString是Object-C語言中用于存儲文本的對象平道。說實在的,它比Swift中的String要強大而且簡便菩浙。
然而巢掺,Swift有一個絕招:String和NSString是“橋接”的,這就是說你可以用NSString代替String劲蜻。這里陆淀,你想要使用屬于NSString的方法replacingCharacters(in:with:),所以你必須使swift知道這個文本是NSString類型的先嬉,而不是String轧苫。
關(guān)鍵字as NSString的作用就是通知swift這個oldText是一個NSString類型的常量。如果你沒有這樣做的話疫蔓,swift會根據(jù)類型推定斷定oldText是一個String對象含懊,這樣就不能使用replacingCharacters(in:with:)方法了。
順便說一下衅胀,String并不是唯一一個和Object-C有橋接的類型岔乔,另一個例子是數(shù)組(Array)可以橋接到Object-C的NSArray上去。因為iOS的架構(gòu)并不完全是由swift寫成的滚躯,所以Object-C的退休時間延后了雏门。

當你讀取到了新的文本之后,你通過計算它的長度檢查它是否為空掸掏,并且來禁用或者啟用Done按鈕:

if newText.length > 0 {
            doneBarButton.isEnabled = true
        } else {
            doneBarButton.isEnabled = false
        }

運行app并且在文本框中敲一些內(nèi)容茁影,然后刪除這些內(nèi)容,Done按鈕就被禁用了丧凤。

唯一的問題是:在最初你還什么都沒輸入的時候Done按鈕是可用的募闲。這樣相當于我們之前的工作都白做了,這是不允許的愿待,所以我們來一起修復這個問題浩螺。

打開故事模版靴患,選定Done按鈕并且打開屬性檢查器,取消選定Enabled選框年扩。

現(xiàn)在一開始的時候Done按鈕就是禁用狀態(tài)了蚁廓。

什么都沒輸入的時候,無法點擊Done按鈕

最后我們來優(yōu)化一下剛才的代碼:

用下面這一行替換掉if語句

doneBarButton.isEnabled = (newText.length > 0)

之前的if語句是這樣的:

if newText.length > 0 {
   // 長度大于0的情況
} else {
   // 長度小于等于0的情況
}

你通過檢查條件newText.length > 0來判斷是否禁用Done按鈕厨幻,如果大于0的話啟用相嵌,否則則禁用。

注意一下這個if語句翻譯過來其實是:如果條件為真則isEnable為真况脆,如果條件為假則isEnable為假饭宾。換而言之,isEnable不是為真就是為假格了。這樣其實就可以簡化為:

doneBarButton. isEnable = the result of the condition

就是我們剛才看到的:

doneBarButton.isEnabled = (newText.length > 0)

其實這里的括號都沒有存在的必要看铆,因為只有一個運算,所以不存在優(yōu)先級盛末。我們可以更加簡化為:

doneBarButton.isEnabled = newText.length > 0

然而弹惦,這樣做會使可讀性變差,所以我總是習慣加上括號悄但。

我們順便來簡單介紹一下Swift中的比較運算符:

大于 >
< 小于
= 大于等于
<= 小于等于
== 相等
!= 不相等

記住這個小把戲棠隐,無論何時你看到這個結(jié)構(gòu):

if some condition {
  something = true
} else {
  something = false
}

都可以替換為:

something = (some condition)

在實際的操作中你使用那個版本都行。我比較喜歡簡短的這種檐嚣,專業(yè)的人都喜歡這種方式助泽。你需要記住的就是當比較運算符總是返回true和false的時候,你都可以用簡短的方式表達它嚎京。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嗡贺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鞍帝,更是在濱河造成了極大的恐慌诫睬,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帕涌,死亡現(xiàn)場離奇詭異岩臣,居然都是意外死亡,警方通過查閱死者的電腦和手機宵膨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炸宵,“玉大人辟躏,你說我怎么就攤上這事⊥寥” “怎么了捎琐?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵会涎,是天一觀的道長。 經(jīng)常有香客問我瑞凑,道長末秃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任籽御,我火速辦了婚禮练慕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘技掏。我一直安慰自己铃将,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布哑梳。 她就那樣靜靜地躺著劲阎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸠真。 梳的紋絲不亂的頭發(fā)上悯仙,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音吠卷,去河邊找鬼锡垄。 笑死,一個胖子當著我的面吹牛撤嫩,可吹牛的內(nèi)容都是我干的偎捎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼序攘,長吁一口氣:“原來是場噩夢啊……” “哼茴她!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起程奠,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤丈牢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瞄沙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體己沛,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年距境,在試婚紗的時候發(fā)現(xiàn)自己被綠了申尼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡垫桂,死狀恐怖师幕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诬滩,我是刑警寧澤霹粥,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布灭将,位于F島的核電站,受9級特大地震影響后控,放射性物質(zhì)發(fā)生泄漏庙曙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一浩淘、第九天 我趴在偏房一處隱蔽的房頂上張望捌朴。 院中可真熱鬧,春花似錦馋袜、人聲如沸男旗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽察皇。三九已至,卻和暖如春泽台,著一層夾襖步出監(jiān)牢的瞬間什荣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工怀酷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留稻爬,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓蜕依,卻偏偏與公主長得像桅锄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子样眠,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

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