寫在前面
我不算是個(gè)資深碼農(nóng)岳悟,有些iOS的編程經(jīng)驗(yàn)。希望找到一種高效的方式來創(chuàng)作出自己的iOS應(yīng)用泼差。大家都知道純代碼寫應(yīng)用的成本是很高的贵少,特別是涉及到UI界面的實(shí)現(xiàn),相當(dāng)耗費(fèi)時(shí)間堆缘。之前自己寫應(yīng)用時(shí)有了解過Storyboard滔灶,也簡單使用過,但隨著最近深入了解它之后吼肥,發(fā)現(xiàn)自己低估了它的作用和影響力录平,因此在這里總結(jié)下最近段時(shí)間學(xué)習(xí)到的內(nèi)容,希望對(duì)Storyboard初學(xué)者有所幫助缀皱。Interface Builder的界面布局如下圖:
(圖片來自Apple官網(wǎng))
1.基礎(chǔ)概念
在學(xué)習(xí)Storyboard的使用萄涯,有三個(gè)概念是最容易混淆的:xib、nib唆鸡、storyboard涝影。
- xib:是一個(gè)可視化文件,可通過拖拽文件進(jìn)行界面創(chuàng)作和布局争占。xib實(shí)際是個(gè)xml文件燃逻,xib = XML nib序目。
- nib:xib編譯之后就得到nib文件,nib= NeXT Interface Builder
- storyboard:大家可以理解為是升級(jí)版的xib伯襟,可以同時(shí)管理多個(gè)xib文件并處理場景與場景之間的跳轉(zhuǎn)猿涨。
2.拖放元素
在storyboard/xib上通過拖放對(duì)象到界面上就能實(shí)現(xiàn)界面元素的創(chuàng)建,與純代碼UI相比可以節(jié)省很多調(diào)試的時(shí)間姆怪,所見即所得是高效的重要方式叛赚。
(圖片來自Apple官網(wǎng))
拖放元素后,可以通過Attributes Inspector上的各種滑塊稽揭、調(diào)色板俺附、大小設(shè)定等方式來進(jìn)行元素屬性的配置(注意只支持大部分,而不是所有溪掀。沒有提供的屬性可通過User Defined Runtime Attributes來進(jìn)行設(shè)置)
3.連線——IBOutlet和IBAction
在Storyboard/xib上通過拖放對(duì)象來完成界面布局后事镣,我們就得到一個(gè)靜態(tài)的界面,那接下來應(yīng)該怎么把這些界面元素與代碼關(guān)聯(lián)起來揪胃,秘密就在于“連線”璃哟。
把storyboard上的界面對(duì)象與代碼關(guān)聯(lián)起來,我們俗稱為連線喊递。因?yàn)樵趚code上的操作就是拖出一條線來把它們進(jìn)行關(guān)聯(lián)随闪。
進(jìn)行連線有兩種方法:
- 選中某個(gè)界面元素,按下Control后拖出線條來進(jìn)行關(guān)聯(lián)骚勘。
- 選中某個(gè)界面元素蕴掏,切換到Connections Inspector界面,在每項(xiàng)后面的圓圈拖出線條來進(jìn)行關(guān)聯(lián)调鲸。
IBOutlet
第一種連線是IBOutlet盛杰,它的作用是把靜態(tài)的界面元素與代碼進(jìn)行關(guān)聯(lián),使得代碼中的變量與界面元素對(duì)應(yīng)起來藐石。關(guān)聯(lián)之后就可通過代碼對(duì)界面元素屬性進(jìn)行操作即供,如更換背景顏色,增加描邊之類的于微。
(圖片來自Apple官網(wǎng))
IBAction
第二種連線是IBAction逗嫡,它的作用是把界面元素的事件與代碼中的方法關(guān)聯(lián)起來,當(dāng)用戶對(duì)元素觸發(fā)了某個(gè)事件之后株依,讓系統(tǒng)執(zhí)行特定的代碼對(duì)用戶的操作進(jìn)行響應(yīng)驱证。例如按鈕被按下后,會(huì)執(zhí)行跳轉(zhuǎn)到另外一個(gè)界面的代碼恋腕。
(圖片來自Apple官網(wǎng))
4.File’s Owner
看到這里抹锄,大家可能有個(gè)疑問:xcode怎么知道浙西界面要與哪個(gè)文件(類)進(jìn)行聯(lián)系,以進(jìn)行接下來的連線操作?答案在于File’s Owner伙单。
File’s Owner描述了xib文件的擁有者是誰(這也是字面的意思)获高,決定了界面元素可以與哪些文件的變量進(jìn)行IBOutlet,決定了界面的事件可以與哪些文件的方法進(jìn)行IBAciton吻育。
設(shè)置File’s Owner:在Xib文件(注意不是storyboard)念秧,選中File’s Owner通過Identity Inspector中設(shè)置xib的Class來起對(duì)指定應(yīng)的擁有者。
- 基于VC創(chuàng)建的xib布疼,默認(rèn)已經(jīng)設(shè)置好對(duì)應(yīng)的File Owner摊趾,所以一般無需自己設(shè)置,如果特殊情況可以指定其他的文件作為其擁有者游两。
- 而基于View創(chuàng)建的xib砾层,一般要指定對(duì)應(yīng)的File’s Owner。
注意:在storyboard已經(jīng)沒有file’s owner這個(gè)概念器罐,但并不妨礙連線。每個(gè)VC上有三個(gè)按鈕渐行,連線時(shí)只要拖線到第一個(gè)按鈕即可進(jìn)行關(guān)聯(lián)轰坊。
5.Storyboard VS Xib
storyboard和xib在界面和操作上大體相同,這里聊下它們之間的差別(歡迎進(jìn)行補(bǔ)充)
- storyboard的文件以.storyboard結(jié)尾祟印,xib文件以.xib結(jié)尾
- storyboard更注重于多個(gè)場景(頁面)的層級(jí)關(guān)系及跳轉(zhuǎn)肴沫,而xib更注重于單個(gè)頁面的布局和復(fù)用性,這可以作為選擇使用storyboard還是xib的參考蕴忆。
- storyboard上只能使用VC颤芬,不能單獨(dú)使用UIview,UIView只能基于VC上進(jìn)行使用套鹅,而xib同時(shí)支持兩者站蝠。這一點(diǎn)也印證了上面提到的兩者的不同傾向。
- storyboard上沒有file’s Owner的概念卓鹿,默認(rèn)通過VC的class的指定其擁有者菱魔。
- storyboard上可以通過segue實(shí)現(xiàn)無需代碼的界面跳轉(zhuǎn),而xib由于管理的是單個(gè)界面吟孙,因此只能通過代碼來實(shí)現(xiàn)界面的切換澜倦。
6.頁面切換Segue
Segue的出現(xiàn),讓無需代碼進(jìn)行頁面切換成為可能杰妓,這是工作高效的第二個(gè)很重要的技能藻治,只需要簡單的設(shè)置幾下技能實(shí)現(xiàn)之前通過代碼實(shí)現(xiàn)的跳轉(zhuǎn),相當(dāng)贊巷挥!Segue實(shí)際是UIStoryboardSegue對(duì)象桩卵。
通過segue可以實(shí)現(xiàn):
- 從一個(gè)頁面切換到另外一個(gè)頁面
- 通過unwind Segue回退到某個(gè)頁面
- 實(shí)現(xiàn)傳參數(shù)
- 可以指定跳轉(zhuǎn)到具體的頁面,也可以進(jìn)行不確定的頁面跳轉(zhuǎn)(實(shí)際上是通過代碼來控制要跳轉(zhuǎn)的目標(biāo)頁面)
跳轉(zhuǎn)到一個(gè)指定的頁面
一般情況下,用戶觸發(fā)了界面上的某個(gè)元素進(jìn)行特定操作后吸占,應(yīng)用執(zhí)行界面的跳轉(zhuǎn)晴叨。
具體操作:在Storyboard的VC上,選中觸發(fā)跳轉(zhuǎn)的元素矾屯,按Control拖線條到目標(biāo)的VC兼蕊,之后在出現(xiàn)的Action Segue菜單中選則切換方式,成功設(shè)置segue后件蚕,在兩個(gè)VC間就會(huì)出現(xiàn)連起來的線孙技。就這么簡單!是不是很實(shí)用排作。
(圖片來自Apple官網(wǎng))
注意觀:不同類型的Segue會(huì)對(duì)應(yīng)不同的圖標(biāo)牵啦,見下圖:
unwind Segue實(shí)現(xiàn)頁面回退
之前大部分情況下是通過代理來實(shí)現(xiàn)頁面間的回退,例如要取消一個(gè)模態(tài)視圖妄痪,需調(diào)用dismissViewControllerAnimation()的方法」現(xiàn)在可以通過Unwind Segue更簡單方便的實(shí)現(xiàn)這樣的回退,這又是個(gè)高效的技能。
具體步驟如下:
- 在回退的目標(biāo)頁面上提供回退處理方法。例如從VC2返回到VC1阱佛,那么回退的方法應(yīng)該寫在VC1上侦副。
- 定義回退方法。回退方法的返回值必須是IBAciton,并帶上UIStoryboardSegue參數(shù)。例如:
@IBAction func close (segue:UIStoryboardSegue)派殷。
該方法方法只需要定義,不需要方法體墓阀。
- 關(guān)聯(lián)毡惜。在VC2觸發(fā)返回操作的元素上按control鍵拖線到Exit圖標(biāo)(每個(gè)VC上方三個(gè)圖標(biāo)中的第三個(gè)),在出來的Action Segue菜單中選剛才定義好的回退方法close()斯撮。這樣就可以實(shí)現(xiàn)頁面的回退虱黄。
segue傳參
有時(shí)在頁面跳轉(zhuǎn)的時(shí)候,需要把參數(shù)傳到新的頁面吮成,使用Segue實(shí)現(xiàn)頁面跳轉(zhuǎn)時(shí)應(yīng)該怎么實(shí)現(xiàn)這一點(diǎn)橱乱?
在跳轉(zhuǎn)即將發(fā)生時(shí)會(huì)調(diào)用prepareForSegue:,因此可以在這個(gè)方法上做文章粱甫。示例代碼:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier=="goToB"{
let bVC = segue.destinationViewController
bVC.testTite = @"hello world"
}
}
segue對(duì)象有個(gè)destinationViewController的屬性可以獲取跳轉(zhuǎn)到的目標(biāo)VC泳叠,這樣就可以在跳轉(zhuǎn)之前把當(dāng)前VC的值賦予目標(biāo)VC的某個(gè)屬性,從而實(shí)現(xiàn)參數(shù)的傳遞茶宵。
順便提一下危纫,當(dāng)segue不止一個(gè)的時(shí)候就需要給它進(jìn)行標(biāo)識(shí),以便在處理跳轉(zhuǎn)的過程中進(jìn)行定制化,就像上面的代碼种蝶,當(dāng)判斷segue的標(biāo)識(shí)為goToB的時(shí)候才進(jìn)行下面的操作契耿。設(shè)定標(biāo)識(shí)符的方法很簡單,選中segue連線螃征,在attribute inspector中設(shè)置identifier就可以了搪桂。
segue配合代碼進(jìn)行不確定的頁面跳轉(zhuǎn)
有時(shí)會(huì)出現(xiàn)這樣的情況,我們確定從A頁面會(huì)跳轉(zhuǎn)到B盯滚、C踢械、D頁面,但具體跳轉(zhuǎn)到哪個(gè)頁面是需要通過邏輯觸發(fā)的魄藕。這種情況應(yīng)該如何用Segue來實(shí)現(xiàn)内列?
- 在.storyboard文件的導(dǎo)航視圖中找到起始VC,右鍵菜單找到Triggered Segues下的manual后面的+背率,拖線到可能要跳轉(zhuǎn)到的VC话瞧。
- 給Segue設(shè)置標(biāo)識(shí)。
- 代碼實(shí)現(xiàn)Segue跳轉(zhuǎn)寝姿。在觸發(fā)的事件響應(yīng)方法IBAciton中嵌入跳轉(zhuǎn)頁面的代碼交排。如點(diǎn)擊按鈕之后,通過邏輯判斷跳轉(zhuǎn)到不同的頁面会油。這時(shí)候个粱,就可以在按鈕的按下事件的響應(yīng)方法上嵌入下面的跳轉(zhuǎn)代碼古毛。
self.performSegue(withIdentifier: "id", sender: sender)
- 這樣就實(shí)現(xiàn)了通過segue設(shè)置頁面的跳轉(zhuǎn)關(guān)系翻翩,通過代碼來控制具體的目標(biāo)頁面,從而實(shí)現(xiàn)不確定的頁面跳轉(zhuǎn)稻薇。
以下內(nèi)容與界面適配有關(guān)嫂冻,發(fā)現(xiàn)網(wǎng)絡(luò)上已經(jīng)有比我自己總結(jié)更好的文章,因此就不在這里搬磚了塞椎。大家可以參考外鏈來學(xué)習(xí)桨仿。
7.屏幕大小適配
在xcode8之前,為了在一個(gè)Storyboard中適配不同的屏幕大小案狠,需要使用相對(duì)抽象的概念——Size Class服傍。但xcode8之后你可以直接選擇不同設(shè)備查看對(duì)應(yīng)界面布局,甚至進(jìn)行界面元素的差異化骂铁。這樣比理解Size Class概念更為人性化吹零。
有興趣了解Size Class的可參考這篇文章:初探 iOS8 中的 Size Class
8.AutoLayout
單靠Size Class無法解決適配問題,真正起作用的是AutoLayout拉庵,它為我們處理同一個(gè)屏幕尺寸下不同旋轉(zhuǎn)方向上的的界面布局提供簡單可行的方案灿椅。
用Apple官方的說法來描述:
AutoLayout是一種基于約束的,描述性的布局系統(tǒng)。 Auto Layout Is a Constraint-Based, Descriptive Layout System.
AutoLayout的位置是使用相對(duì)位置的約束來定義的茫蛹,簡單來說就是通過與B的相對(duì)距離來定義A的位置操刀。這樣,不管屏幕的旋轉(zhuǎn)情況如何婴洼,我只要告訴你這個(gè)元素相對(duì)于屏幕邊緣的距離就可以定義元素的位置骨坑。這樣比逐個(gè)處理屏幕的旋轉(zhuǎn)情況來得更加高效。
具體介紹可參考:WWDC 2012 Session筆記——AutoLayout(自動(dòng)布局)入門
9.來點(diǎn)新玩意
IBInspectable
@IBInspectable是xcode6之后才出現(xiàn)的窃蹋,用來修飾屬性卡啰,使得自己定義的屬性可以出現(xiàn)在interface builder的界面上,進(jìn)行可視化編程警没。
@property(nonatomic,assign) IBInspectable CGFloat cornerRadius;
定義后匈辱,在storyboard查看對(duì)應(yīng)VC的Attributes Inspector就會(huì)神奇的發(fā)現(xiàn)多了一個(gè)可設(shè)置的屬性。
IBDesignable
@IBdesignable也是Xcode6之后才引入的杀迹,主要作用是亡脸,可以在不運(yùn)行的情況下,就能把代碼效果顯示在Storyboard/Xib上树酪。
不過有幾點(diǎn)要注意的:
- @IBDesignable需寫在Class前面浅碾。
- 要想IBDesignable起作用必須把代碼寫在drawRecr方法中才能顯示出來。
更多IBInspectable和IBDesignable的介紹续语,可戳這里垂谢。
總結(jié)
最后再次強(qiáng)調(diào)下幾個(gè)提高產(chǎn)出效率的點(diǎn):
- 在storyboard/Xib進(jìn)行UI界面的布局。
- 通過Segue來是實(shí)現(xiàn)頁面間的跳轉(zhuǎn)疮茄。
- 通過AutoLayou來適配不同的屏幕尺寸和旋轉(zhuǎn)方向滥朱。
另外貼個(gè) Xcode的官方介紹文檔 ,可更深入的了解Xcode的使用力试。
(如發(fā)現(xiàn)內(nèi)容出現(xiàn)紕漏徙邻,望各位大牛指正。如有補(bǔ)充畸裳,歡迎留言缰犁,謝謝。)