設(shè)計師應(yīng)該了解的iOS應(yīng)用開發(fā)基礎(chǔ)知識
作為一名交互或視覺設(shè)計師,你希望順應(yīng)當(dāng)前大環(huán)境的發(fā)展趨勢,向移動領(lǐng)域拓展自己的視野和能力,于是決定挽起袖子學(xué)習(xí)iOS應(yīng)用開發(fā)。興奮之余,你開始做一些初步的研究,但是很快發(fā)現(xiàn),除非自己有足夠豐富的編程經(jīng)驗,否則要實現(xiàn)目標(biāo)還真不是件易事。
確實是這樣。蘋果提供的開發(fā)文檔主要是面向技術(shù)人員的,市面上多數(shù)iOS開發(fā)書籍都會一上來就問你是否掌握了足夠的Objective-C知識,而網(wǎng)上各種教程的質(zhì)量又參差不齊,其中有不少還是面向著很舊版本的iOS系統(tǒng)及開發(fā)工具的。
本文的目的就是幫助各位設(shè)計師在最短的時間內(nèi),以實戰(zhàn)的方式探索iOS應(yīng)用開發(fā)工具及相關(guān)的基礎(chǔ)知識。我們將一同了解應(yīng)用開發(fā)流程中的一些重要環(huán)節(jié),包括理論講解及方法演示,即使你沒什么編程經(jīng)驗也沒問題。
我們的實戰(zhàn)案例是一款非常簡單的、用來展示設(shè)計作品的應(yīng)用,如下圖所示:
本地(原生)開發(fā)方式
所謂“本地”,即是指通過蘋果原生的開發(fā)工具(SDK)及Objective-C語言開發(fā)iPhone和iPad應(yīng)用的方式。在我們對這套方法進行探索之前,最好稍微花點時間了解一下還有哪些替代方案,以及我們之所以選擇原生開發(fā)方式的原因。
也許很多人已經(jīng)聽說過Web App及“混合型應(yīng)用”這樣的說法,這些就是所謂的“替代方案”。我們確實可以使用基于HTML5、CSS、JavaScript的Web前端開發(fā)技術(shù)打造應(yīng)用,這其中最為常見的解決方案包括Titanium Mobile、PhoneGap、jQuery Mobile以及Sencha Touch等框架。通過這種方式開發(fā)的應(yīng)用通常具有很好的跨平臺特性。
不過,通過這種非原生方式開發(fā)的應(yīng)用有著明顯的弊端?;跒g覽器(Web App)或“原生應(yīng)用殼”(混合型應(yīng)用)的運作方式使它們的效率無法與本地應(yīng)用媲美,而且對硬件功能的訪問及利用能力也是非常有限的。此外,代碼框架本身 也是需要學(xué)習(xí)的,它們有著各自不同的使用方式,在框架之外還有各種擴展庫需要摸索。另外,框架本身的質(zhì)量和成熟程度也是必須考慮的因素。
還有其他一些第三方開發(fā)方案可以考慮,例如Cocos 2D for iPhone和PugPig。這類方案允許你將框架文件與Objective-C對象建立關(guān)聯(lián),以達(dá)到特定的目標(biāo),例如創(chuàng)建游戲或雜志類應(yīng)用等。要使用這類技術(shù),你最好也要對蘋果本地開發(fā)工具包具有基本程度的了解。
準(zhǔn)備工作
正式起步前的準(zhǔn)備工作包括兩方面:
硬件:一臺運行著最新或新近版本OS X系統(tǒng)的Mac機,包括MacBook(Pro/Air)、Mac mini、iMac或是Mac Pro均可。
軟件:蘋果的Xcode應(yīng)用。
Xcode可以從Mac應(yīng)用商店(Mac App Store)或是蘋果的開發(fā)者站點中免費下載到,大約1.5GB的樣子。
圖片資源
在等待Xcode下載完成的過程中,我們可以同步開始圖片方面的工作。
由于要為普通屏幕(320×480)和Retina屏幕(640×960)各自準(zhǔn)備一套圖像資源(最新的iPhone5規(guī)格為640×1136), 我們應(yīng)該在Photoshop中盡量多的使用矢量圖形(vector shape)、圖層樣式(layer style)以及智能對象(smart object)等技術(shù),以確保圖像的無損縮放。比較合理的流程是從Retina版本入手進行構(gòu)建,然后等比縮放到普通版本的規(guī)格。在縮放過程中,一些元素 的細(xì)節(jié)有可能發(fā)生變形,記得做好手動調(diào)整。
另外,我們還可以在網(wǎng)上找到很多原生風(fēng)格的iPhone界面PSD模板,其中比較著名的一款是來自Teehan和Lax的iPhone 4 GUI PSD。如果要打造的應(yīng)用在界面方面以iOS原生風(fēng)格為主,那么這類模板可以幫助我們節(jié)省掉很多時間。即使你更傾向于定制化的用戶界面,這些模板同樣可以在控件規(guī)格、布局規(guī)則等方面提供精確的參考。(相關(guān)閱讀:先了解規(guī)則,再尋求創(chuàng)新 - 關(guān)于iOS應(yīng)用界面自定義)
在Photoshop或是你更習(xí)慣的圖像編輯工具中創(chuàng)建一個新文檔,規(guī)格如下:
尺寸:640×960(pixels)
DPI:72
色彩模式:RGB
由于本文的焦點主要將集中在開發(fā)的基礎(chǔ)知識上,所以在視覺設(shè)計方面不做深入探討。更多關(guān)于iOS界面設(shè)計技術(shù)及流程方面的信息,可以參考Marc Edwards的Designing for iPhone 4 Retina Display一文。
關(guān)于圖片導(dǎo)出的小貼士
雖然你可以在應(yīng)用中使用多種格式的圖片,不過鑒于alpha通道及無損壓縮等方面的考慮,我們最為推薦的仍是PNG格式。
多數(shù)情況下,要將按鈕導(dǎo)出為不包含文案的背景圖片,以便更加靈活的在開發(fā)環(huán)境中調(diào)整文字屬性,或是對多語種進行支持。
對于按鈕的背景圖片,要確保實際按鈕的部分(不包括陰影或外發(fā)光等效果的區(qū)域)處于背景圖片的正中,因為我們在Xcode的Interface Builder當(dāng)中很難對背景圖片及前景文字之間的位置關(guān)系進行精密的調(diào)整。很多時候,我們需要在制作背景圖片的過程中,在按鈕的另外一側(cè)添加一塊空白的 區(qū)域,以彌補陰影效果所占據(jù)的空間,確保按鈕自身處于正中央。
在設(shè)計方案允許的情況下,盡可能將那些在視覺上疊加在一起的元素直接保存在一張背景圖片當(dāng)中,而不要留到開發(fā)環(huán)節(jié)里再進行層疊處理,否則成本將會變 的很高。另外,這樣做也有助于減少資源文件的數(shù)量,提高應(yīng)用運行的效率,減少內(nèi)存占用。只有那些需要對用戶行為進行交互響應(yīng)的界面元素需要獨立的背景圖片 或是動畫效果。
在所有適用于Retina屏的圖片文件名中增加特殊的后綴“@2x”作為標(biāo)示,使系統(tǒng)能夠進行識別:
image.png:適用于普通屏幕。
image@2x.png:適用于Retina屏幕。
可以嘗試使用SuperSlicr這樣的自動化批處理腳本對PSD中的UI元素進行格式化及導(dǎo)出。
所有的資源文件都會保存在app包(app bundle)的同一個路徑當(dāng)中,所以文件名不能有重復(fù)的情況。
Photoshop不大擅長對PNG圖片進行壓縮??梢栽囍褂胕mageOptim這樣的工具減小圖片尺寸,然后再導(dǎo)入到Xcode當(dāng)中。另外,Xcode本身也會對導(dǎo)入過來的圖片進行一定程度的壓縮,不過有時反而會增加圖片的尺寸。
Xcode概覽
Xcode已經(jīng)安裝好了?
接下來我們?nèi)ハ螺d一套用于本次案例學(xué)習(xí)的模板文件,其中包括一些PSD、PNG資源,還有一些用來起步的代碼文件。進入里面的Begin Here文件夾,找到Portfolio.xcodeproj文件,雙擊打開。
文件加載成功之后,點擊左側(cè)導(dǎo)航欄(Navigator)中的項目(Portfolio,1 target,iOS SDK),這時我們就可以在編輯區(qū)中看到這個項目的概況信息了,如下圖所示。關(guān)于這些概況信息的用處,我們稍后解釋。
點擊左側(cè)導(dǎo)航欄當(dāng)中項目名稱旁邊的箭頭,我們可以看到一個資源列表,里面包含了當(dāng)前項目所涉及到的所有資源文件,例如代碼和圖片等。我們把注意力放在Portfolio路徑當(dāng)中,其中有三個類型的文件:
.h文件:頭文件(header,也可稱為interface文件)。
.m文件:消息文件(message,也可稱為implementation文件)。
.xib文件:在Interface Builder中進行界面可視化編輯的XML文件,出于歷史原因,通常也被稱為NIB文件。
中間編輯區(qū)(Editor)所呈現(xiàn)的內(nèi)容會根據(jù)當(dāng)前正在執(zhí)行的任務(wù)而發(fā)生變化。當(dāng)我們像之前那樣點擊了導(dǎo)航欄中的項目名稱時,這里展示的就是目標(biāo)概 況(Target Summary),其中包括當(dāng)前應(yīng)用的一些基本信息,例如設(shè)備類型、iOS版本、屏幕定向方案等等。此外,應(yīng)用的圖標(biāo)及加載圖片也是在這里進行設(shè)置的;我 們將會在后文中進行演示。
在導(dǎo)航欄中單擊Portfolio路徑中的AppDelegate.m文件,編輯區(qū)就會相應(yīng)的進入代碼編輯狀態(tài)。
接下來單擊Portfolio路徑中的MainWindow.xib文件,這時編輯區(qū)所呈現(xiàn)的就是用于編輯用戶界面的Interface Builder,如下圖所示。我們通常會在這里對應(yīng)用界面做最基本的構(gòu)建。
右側(cè)的檢查器(Inspector)當(dāng)中共有6組工具,其中后面4組是開發(fā)工作當(dāng)中最常用 的,從右到左依次為連接檢查器(Connection Inspector)、規(guī)格檢查器(Size Inspector)、屬性檢查器(Attributes Inspector)、識別檢查器(Identity Inspector)。
另外一個最常用的操作莫過于Xcode左上角的“運行(Run)”按鈕了。這個操作會將項目代碼編譯成為應(yīng)用,并在iOS設(shè)備模擬器中運行,以便我們直接查看程序的工作情況,而不必每次都部署到實際設(shè)備中。
不妨現(xiàn)在就點擊“運行”按鈕或使用快捷鍵Command+R,來看看我們的模板項目打包成應(yīng)用之后的樣子:
什么也沒有。iPhone模擬器的工作機制與實際設(shè)備差不多,Home按鍵是可以點擊的, 其他的一些內(nèi)置應(yīng)用也都是可以正常工作的,包括Safari、照片、聯(lián)系人、Game Center、最新的Passbook等等,有興趣的話可以玩玩看。另外,我們還可以在“Stop”按鈕右側(cè)的下拉列表中選擇iPad作為模擬設(shè)備。
更多關(guān)于Xcode的使用方法,可以參考蘋果官方的“Xcode 4 User Guide”。
別走開,下頁繼續(xù)
#p#
將圖片導(dǎo)入Xcode
我們下載的模板包當(dāng)中是包括圖片文件的,不過項目默認(rèn)是不會將這些資源文件加載進來的,我們必須手動導(dǎo)入。方法有兩種:你可以在左側(cè)導(dǎo)航欄當(dāng)中 Control單擊Images文件夾,選擇“Add Files to 'Portfolio'”,然后找到模板包當(dāng)中PNGs路徑下的全部文件,執(zhí)行添加(Add);或者也可以首先在Finder中找到這些文件,然后全部拖 到Xcode導(dǎo)航欄的Images文件夾中。
如果采用第二種方式,在執(zhí)行導(dǎo)入的時候,Xcode會提供一些操作選項,記得勾選其中的“Copy items into destination group's folder”,確保資源文件最終會被打包到應(yīng)用項目當(dāng)中。
應(yīng)用界面的可視化編輯
iOS開發(fā)的圈子當(dāng)中始終存在一個爭論——是完全通過代碼的方式創(chuàng)建應(yīng)用更好,還是使用Interface Builder更加直觀的構(gòu)建界面來的更好些。兩種方式都是可行的,而且它們在本質(zhì)上可以說是互補而不是矛盾的關(guān)系,具體的開發(fā)策略還是由實際項目的特點所決定。
傾向于純代碼方式的開發(fā)者們也許真的忽視了可視化編輯工具在界面創(chuàng)建過程中所體現(xiàn)出的高效與直觀。對于我們這些習(xí)慣了Adobe系列工具的設(shè)計師來 說,可視化編輯的方式無疑是最好的切入點;而且我們的案例是很典型的基于視圖(view)的應(yīng)用,在這里使用Interface Builder進行界面構(gòu)建也是最合理的。
首先,我們來看看怎樣創(chuàng)建一些可以通過標(biāo)簽欄(Tab Bar)進行切換的界面,或者說視圖(view)。在Xcode左側(cè)的導(dǎo)航欄中點擊MainWindow.xib,進入Interface Builder編輯模式。在右下角的庫(Library)中選擇“Show the Object Library”圖標(biāo)(看上去像個立方體的那個),在下面的列表中找到“View Controller”。
拖拽一個View Controller對象到編輯區(qū)左側(cè)的文檔結(jié)構(gòu)列表(Document Outline)當(dāng)中,并在"Tab Bar Controller"上面放開。此時后者會展開,一個View Controller嵌套在里面。
重復(fù)執(zhí)行兩次這樣的操作,使Tab Bar Controller當(dāng)中包含3個View Controller,此時我們也可以在編輯區(qū)當(dāng)中看到,默認(rèn)的View Controller的標(biāo)簽欄里已經(jīng)有了3個未命名的Tab,如下圖所示:
什么是View Controller?
View(視圖)和Controller(控制器)都是MVC開發(fā)模式(Model View Controller)的組成部分。這種開發(fā)模式旨在將程序的數(shù)據(jù)、業(yè)務(wù)邏輯與表現(xiàn)進行分離(類似前端的“內(nèi)容、樣式、行為分離”)。其中"Model" 包括數(shù)據(jù)和算法等方面,“View”涉及軟件的人機交互界面,而“Controller”負(fù)責(zé)將這兩者銜接起來,對用戶行為進行處理;而View Controller即是指專門負(fù)責(zé)某個特定View的Controller。
創(chuàng)建類(Class)
我們需要創(chuàng)建一些“類”來生成視圖。在Objective-C這樣的面向?qū)ο缶幊陶Z言當(dāng)中,“類”用來定義對象(Object)所共有的屬性與方法。通過“類”,我們可以實例化出更多的同類對象。
在我們的案例當(dāng)中,每個視圖都是一個對象,它們有各自的內(nèi)容與行為特征。所以我們需要創(chuàng)建3個不同的類,以便對每個視圖的屬性和方法進行定義。這些類所扮演的就是View Controller的角色。
要創(chuàng)建新的類,使用快捷鍵Command+N,在左側(cè)的列表中選擇“Cocoa Touch”中的“Objective-C class”,如下圖所示:
點擊“Next”,在“Class”文本框中將這個類命名為“HomeViewController”,在下面的“Subclass of”列表中選擇“UIViewController”,并勾選“With XIB for user interface”。
繼續(xù)點擊“Next”,在接下來的對話窗中,將類文件的保存路徑設(shè)置為“Begin Here>Portfolio”,點擊“Create”。
以相同的方法再創(chuàng)建兩個類,分別命名為“PortfolioViewController”和“ContactViewController”。之后,你可以手動在導(dǎo)航欄中對文件進行拖放排序,使它們看上去更符合邏輯:
為Tab與視圖建立關(guān)聯(lián)
回到MainWindow.xib當(dāng)中,在文檔結(jié)構(gòu)列表里選中我們之前添加的第一個View Controller,在右側(cè)的識別檢查器(Identity Inspector)中,展開“Class”下拉列表,選擇其中的“HomeViewController”。
接下來切換到屬性檢查器(Attributes inspector),在“Title”中輸入“Home”,并在“NIB Name”中選擇“HomeViewController”。
在文檔結(jié)構(gòu)列表中展開這個View Controller,選中其中的“Tab Bar Item”,然后到屬性檢查器當(dāng)中將“Title”設(shè)置為“Home”,并在“Image”下拉列表中選擇我們之前導(dǎo)入的圖片文件之一,tab- icon-home.png,這里你并不需要特別為Retina屏幕指定帶有@2x后綴的文件,應(yīng)用會在運行的時候自動識別。
以同樣的方法對另外兩個View Controller進行操作,將它們分別與“PortfolioViewController”、“ContactViewController”建立 關(guān)聯(lián)、掛上NIB文件,并為它們各自的Tab Bar Item設(shè)置相應(yīng)的Title(Portfolio、Contact)與圖標(biāo)(tab-icon-portfolio.png、tab-icon- contact.png)。
Tab在高亮狀態(tài)時的顏色也是可以定義的。在文檔結(jié)構(gòu)列表中選中“Tab Bar”對象,然后在右側(cè)的屬性檢查器中找到“Image Tint”,在其中設(shè)置我們所需要的配色方案。不過這里所做的設(shè)置只有在iOS 5以上的系統(tǒng)中才會有效,對于iOS 4以及更低版本的系統(tǒng)來說,高亮狀態(tài)仍然時默認(rèn)的藍(lán)色。
我們已經(jīng)為Tab與視圖建立了關(guān)聯(lián),要檢視它們能否正常工作,我們還需要在每個視圖當(dāng)中添加一些范例內(nèi)容。
在Xcode左側(cè)的導(dǎo)航欄中選擇HomeViewController.xib,然后從右側(cè)的對象庫中拖拽一個Label控件到編輯區(qū)當(dāng)中的空白View上面。雙擊該控件,將文案更改為“Home”。
在PortfolioViewController.xib與ContactViewController.xib當(dāng)中也執(zhí)行同樣的操作,Label的文案相應(yīng)的更改為“Portfolio”和“Contact”。
現(xiàn)在點擊“Run”按鈕,或使用快捷鍵Command+R來運行一下叭。我們可以在iPhone模擬器中看到,應(yīng)用的標(biāo)簽欄已經(jīng)可以正常的切換界面了。不賴!
別走開,下頁繼續(xù)
#p#
向視圖中添加圖片和文字
要通過Interface Builder向視圖當(dāng)中添加圖片和文字,我們首先需要創(chuàng)建一些對應(yīng)著不同類型內(nèi)容的“容器”,也就是“Image View”與“Text View”。與添加View Controller的方式相同,我們也需要將這兩類View從右側(cè)的對象庫當(dāng)中拖拽出來放到界面當(dāng)中。我們還可以在規(guī)格檢查器(Size inspector)中對這些容器進行精準(zhǔn)的定制,包括布局位置、尺寸等。
而在屬性檢查器(Attributes inspector)中,我們可以為圖片容器指定其中所要顯示的圖片,也可以控制文字容器的各種屬性。
接下來我們要向HomeViewController.xib當(dāng)中添加圖片。首先刪除之前的Label控件,從庫中拖拽一個Image View到界面當(dāng)中,在屬性檢查器當(dāng)中的“Image”下拉列表里選擇“home-bg.png”,然后將“Mode”設(shè)置為“Top Left”。
到規(guī)格檢查器(Size inspector)中,確保其中的4個屬性值分別為“0”、“-20”、“320”、“480”,如下圖所示:
接下來,拖拽一個Text View到界面中,雙擊編輯其中的文案,例如更改為“A Catchy Slogan Here”,在屬性檢查器中設(shè)置為居中對齊,將字色設(shè)置為白色,并禁用背景色,然后將Font類型更改為“Custom”,將其他屬性設(shè)置為“Snell Roundhand,Regular,24”。
現(xiàn)在我們的HomeViewController.xib看上去大致是這樣的:
因為這三個界面都是被放置在Tab Bar Controller體系當(dāng)中的,也就是說我們在設(shè)計這些單獨界面的時候必須考慮到底部標(biāo)簽欄的占位。Xcode可以幫助我們在界面當(dāng)中模擬這類全局元素 的占位情況。確保在Xcode左側(cè)的導(dǎo)航欄里選中HomeViewController.xib文件,在文檔結(jié)構(gòu)列表中選擇“View”對象,然后在右側(cè) 的屬性檢查器(Attributes inspector)中找到最上面的“Simulate Metrics”一欄,在“Bottom Bar”中選擇“Tab Bar”,如下圖所示:
這個功能并不會向?qū)嶋H應(yīng)用里又添加一個標(biāo)簽欄,它只是為我們提供一個可視化的設(shè)計指引,幫助我們對界面元素進行更精準(zhǔn)的定位。
接下來,我們可以向Portfolio及Contact界面中添加圖片和文字內(nèi)容了。具體的樣式可以參考本文開始時的目標(biāo)演示圖片,或參考模板包當(dāng)中提供的PSD文件。
在Portfolio界面當(dāng)中創(chuàng)建案例縮略圖,以及在Contact界面中創(chuàng)建聯(lián)系方式按鈕時,我們需要使用對象庫中的Round Rect Button控件,而不是之前那樣使用Image View;因為這些地方都是需要響應(yīng)用戶的操作并由此觸發(fā)相關(guān)行為的,按鈕類的控件可以幫我們實現(xiàn)這個目標(biāo)。將Round Rect Button拖拽到界面內(nèi),到右側(cè)的屬性檢查器當(dāng)中,將按鈕類型(Type)設(shè)置為“Custom”,然后就可以通過下面的“Image”屬性為其設(shè)置具 體的背景圖片了;如果需要的話,還可以進入規(guī)格檢查器(Size inspector)當(dāng)中對按鈕的尺寸進行設(shè)置,使其符合按鈕圖片的大小。
3個界面都打造完畢后,點擊“Run”按鈕或使用快捷鍵Command+R來運行應(yīng)用,通過iPhone模擬器來檢視當(dāng)前的工作成果。
其他技巧
在iPhone模擬器中點擊Home按鍵回到首屏,你會發(fā)現(xiàn)我們的App圖標(biāo)只是一個干巴巴的白板,在應(yīng)用被打開的時候也沒有任何額外的加載圖像。
回到Xcode中,點擊導(dǎo)航欄中的Portfolio項目圖標(biāo),此時內(nèi)容區(qū)會呈現(xiàn)出應(yīng)用的信息概況。在其中找到“App Icons”和“Launch Images”,這里就是我們?yōu)閼?yīng)用添加圖標(biāo)和加載圖像的地方了。
設(shè)置的方法很簡單,在Finder里面找到模板包App Icons路徑下的相關(guān)圖片文件,直接拖拽到那4個空位當(dāng)中就OK了。
如果要自己制作應(yīng)用圖標(biāo),在尺寸方面要符合以下規(guī)格(以像素計):
標(biāo)準(zhǔn):57×57
Retina:114×114
加載圖像的尺寸則與屏幕一致:
標(biāo)準(zhǔn):480×320
Retina:960×640
除了在iPhone當(dāng)中顯示以外,應(yīng)用圖標(biāo)的使用環(huán)境還有很多,例如兩種規(guī)格的iPad、系統(tǒng)設(shè)置(Settings)、Spotlight搜索結(jié)果、iTunes等等。這篇文章很詳細(xì)的給出了這些上下文環(huán)境中所需的圖標(biāo)規(guī)格,另外也可以參考iOS Human Interface Guidelines對于圖標(biāo)規(guī)格及使用方法的說明。
值得一提的是,iOS會自動為你的圖標(biāo)添加圓角和高光,所以在制作的時候你并不需要自己處理這些效果。如果不希望系統(tǒng)為圖標(biāo)添加高光效果,可以在之前設(shè)置圖標(biāo)的地方勾選“Prerendered”。下圖演示的是勾選“Prerendered”前后的效果對比:
要改變圖標(biāo)下面顯示的應(yīng)用名稱,點擊應(yīng)用概況中的“info”選項卡,這里所呈現(xiàn)的就是應(yīng)用的.plist文件當(dāng)中的內(nèi)容。.plist是一個XML文件,里面包含了應(yīng)用的主要設(shè)置信息:
其中的一些信息,例如“Main nib file base name”,所指向的是應(yīng)用在第一次打開時需要加載的資源文件。其他信息,例如“Bundle Identifier”,則與通過iTunes Connect向App Store提交應(yīng)用時的相關(guān)環(huán)節(jié)有關(guān)。
在這些信息中找到“Bundle display name”一項,將右側(cè)的“${PRODUCT_NAME}”修改為你想要的名稱即可。
輔助編輯器(Assistand Editor)
到目前為止,我們的自定義按鈕是可以對點擊動作作出響應(yīng)的,不過也僅此而已,它們還不會做任何其他事情。為了使它們能夠工作起來,我們需要借助輔助編輯器的幫助來寫一些代碼。
在Xcode左側(cè)的導(dǎo)航欄當(dāng)中選擇ContactViewController.xib,然后到Xcode界面的右上角找到輔助編輯器按鈕,選中它:
在這種模式下,編輯界面會被分割為兩部分,其中左側(cè)是 ContactViewController.xib的可視化編輯界面,右側(cè)是與其對應(yīng)的頭文件,即ContactViewController.h。我 們可以在下圖中看到,文檔結(jié)構(gòu)列表和右側(cè)邊欄已經(jīng)被收起了,以便為兩個編輯視圖提供更多的空間。你可以到Xcode菜單中的“View”一項中找到相關(guān)的 切換操作。另外你大概也發(fā)現(xiàn)了,圖中代碼編輯區(qū)的樣式風(fēng)格與你的有所不同,這是因為我(英文原文作者)使用了“Dusk”主題;你可以在 Xcode→Preferences的“Fonts and Colors”更改代碼編輯區(qū)的主題。
別走開,下頁繼續(xù)
#p#
聲明屬性(Property)與方法(Method)
一個“類”通常包含特定的“屬性”和“方法”。我們可以將“屬性”理解為“類”所擁有的特性特征,而“方法”則是指“類”能做些什么。
當(dāng)我們向ContactViewController中添加按鈕時,我們需要將這個按鈕聲明為ContactViewController類的屬性,并通過“方法”告訴按鈕在被點擊時應(yīng)該做怎樣的反應(yīng)。
在ContactViewController.h文件中,我們可以看到如下代碼:
其中,第一行代碼的作用是讓我們的類可以訪問UIKit框架當(dāng)中的各種預(yù)置的UI類。
接下來一行(@interface)的作用是將ContactViewController聲明為UIViewController的一個子類。UIViewController是在UIKit庫中預(yù)先定義的,它的子類可以繼承它的所有特性(包括屬性和方法)。
我們可以在@interface與@end之間聲明各種自定義的屬性和方法。按住control鍵,從 ContactViewController.xib里的“WWW”按鈕上拖出一條導(dǎo)線,一直拉到.h文件的代碼中@interface與@end之間的 部分,釋放。這時會出現(xiàn)一個對話窗:
確保“Connection”當(dāng)中所選的是“Outlet”,并在“Name”里輸入“websiteButton”,點擊“Connect”,Xcode會自動生成一段代碼。
接下來再執(zhí)行一次相同的拖放操作,這次,在對話窗中為“Connection”選擇“Action”,并在“Name”中輸入“openWebsite”,點擊“Connect”,Xcode同樣會自動生成一段代碼。
到目前為止ContactViewController.h中的代碼看上去應(yīng)該是這樣的:
還不賴,不過這些代碼都是什么意思?
@property用來聲明一個新的屬性,括號中是兩個參數(shù),其中“retain”涉及內(nèi)存管理,我們將在后文中講到;而“nonatomic”則 與多線程管理相關(guān),多數(shù)的屬性都要聲明為nonatomic,禁用多線程。接下來是關(guān)于返回類型的聲明,其中“IBOutlet”代表這個屬性是綁定于用 戶界面中某個特定的控件的;“UIButton *websiteButton”的作用是將當(dāng)前屬性命名為“websiteButton”,并使其繼承UIKit中定義的UIButton類。
接下來一行代碼用來聲明新的方法。其中的“- (IBAction)”同樣用來將方法與.xib文件中的界面控件綁定起來。“openWebsite”是這個方法的名稱,冒號后面的“(id)sender”是參數(shù),用來傳遞產(chǎn)生動作的對象信息,不過我們現(xiàn)在用不到它。
也許你已經(jīng)注意到了,我們在創(chuàng)建View Controller類的時候,名稱都是以大寫字母開頭的,但屬性和方法的名稱卻不是這樣。這是面向?qū)ο缶幊陶Z言的一種公約,即“類的命名以大寫字母開頭,屬性(變量)和方法(函數(shù))的命名以小寫字母開頭”。
我們之前演示的“拖動+自動生成代碼”的方法是很方便的。我們當(dāng)然也可以自己手動編碼,只是使用輔助編輯器會更加快捷一些。
屬性合成(Synthesis)與內(nèi)存管理
現(xiàn)在,我們將編輯器切換回標(biāo)準(zhǔn)模式(Standard Editor),彈擊選中ContactViewController.m,在大約12行的地方,你可以看到系統(tǒng)幫我們自動生成的代碼:
這會告訴編譯器在構(gòu)建應(yīng)用的時候為屬性生成設(shè)置器(setter)與訪問器(getter),我們不需要手動編寫代碼就可以使程序具有訪問和設(shè)置屬性值的能力。
再下面,找到這兩行代碼:
覺得眼熟?之前在ContactViewController.h當(dāng)中,系統(tǒng)確實自動生成了類似的代碼,不過在.h文件中的代碼只是一種“聲明”,真正編寫方法函數(shù)還是要在.m文件中進行。具體來說,我們需要將按鈕的反映行為編寫到這里。
你還可以在.m文件中找到類似下面這樣的代碼:
這段代碼與內(nèi)存管理有關(guān)。內(nèi)存管理對于移動應(yīng)用編程來說是非常重要的,因為移動設(shè)備在內(nèi)存方面的資源確實很有限。當(dāng)websiteButton屬性被定義 時,通過“retain”參數(shù),系統(tǒng)會將一部分內(nèi)存分配給這個屬性。“retain”的具體作用是告訴系統(tǒng)分配出一定的內(nèi)存,并且在我們進一步下達(dá)命令之 前不要將這部分內(nèi)存收回。
而“dealloc”方法只會在當(dāng)前View的實例被銷毀時執(zhí)行,所以在這個方法中添加“websiteButton release”就相當(dāng)于告訴系統(tǒng):“你可以在這里收回這部分內(nèi)存資源了,我們不再需要它了”。如果沒有這行代碼,那么即使界面已經(jīng)切換、 websiteButton不再存在,這部分內(nèi)存依然在被占用;這種情況就叫做“內(nèi)存泄漏(memory leak)”。如果在開發(fā)過程中不做相關(guān)處理,那么這種情況就會逐漸累加起來,導(dǎo)致程序運行效率低下甚至崩潰,或是造成系統(tǒng)電量損耗等其他不良后果。
幸運的是,對應(yīng)著iOS 5以上版本的SDK當(dāng)中增加了ARC機制(Automatic Reference Counting),它可以幫助我們進行自動化的內(nèi)存管理。在創(chuàng)建新項目的時候,你可以選擇是否啟用ARC。在當(dāng)前案例中,我們并沒有用到它,因為我們要 在這里對相關(guān)知識進行簡要的介紹。
代碼綁定
之前使用輔助編輯器為按鈕自動創(chuàng)建屬性和方法的時候,系統(tǒng)不僅幫我們生成了相關(guān)的代碼,而且還對按鈕控件與相關(guān)代碼進行了綁定。
選擇ContactViewController.xib,展開文檔結(jié)構(gòu)列表,在“Placeholders”下,選擇“File's Owner”,它所代表的就是整個ContactViewController類。現(xiàn)在到Xcode右側(cè),打開連接檢查器(Connections inspector),看上去應(yīng)該是這樣的:
在“Outlets”當(dāng)中,我們可以看到,websiteButton屬性已經(jīng)被關(guān)聯(lián)到了.xib文件的按鈕控件上。
而在“Received Actions”里,openWebsite方法也已經(jīng)與該按鈕的“Touch Up Inside”事件建立了關(guān)聯(lián)。這個事件所代表的就是用戶在界面中輕觸按鈕并抬起手指的整個動作,它是按鈕控件的默認(rèn)事件。
手動編寫Objective-C代碼
接下來我們要告訴按鈕在被點擊之后應(yīng)該做些什么。
在ContactViewController.m中,將定義openWebsite方法的代碼更新為:
首先,我們在第59行的代碼中創(chuàng)建了一個臨時變量“webAddress”,用來存儲一段包含特定URL(http:''www.apple.com")的字符串。這里的寫法是一種比較快捷的方式,系統(tǒng)可以自動為NSURL實例分配內(nèi)存,也會在需要的時候自動釋放。
而后面的代碼則告訴系統(tǒng)可以使用相關(guān)的應(yīng)用(例如Safari)來打開這個鏈接。
對于Contact界面中的其他按鈕,我們也可以通過類似的步驟來設(shè)定響應(yīng)規(guī)則。將上面代碼中的“openURL:”替換為“mailto:”,可以使應(yīng)用觸發(fā)默認(rèn)郵件客戶端執(zhí)行相關(guān)的郵件工作,而“tel:”則可調(diào)出系統(tǒng)的撥號鍵盤界面,直接撥打預(yù)設(shè)好的電話號碼。
使界面以模態(tài)的方式呈現(xiàn)
當(dāng)前的Portfolio界面中有一些作品的縮略圖,我們希望用戶在點擊它們的時候,對應(yīng)的大圖可以彈出。
要實現(xiàn)這一點,我們可以創(chuàng)造模態(tài)視圖,使新界面以動畫過渡的方式呈現(xiàn)出來,并覆蓋在其他界面之上。
創(chuàng)建模態(tài)視圖
要創(chuàng)建模態(tài)視圖并不難。首先,我們要創(chuàng)建一個新的類,名字叫做BigImageViewController,具體方式與我們之前創(chuàng)建3個自定義類是相同的。
然后打開BigImageViewController.xib文件,向界面中添加一個Image View作為圖片容器,并將它的“Image”設(shè)置為portfolio-modal-bg.png圖片文件。接下來,在左上角添加一個類型為 “Custom”的圓角按鈕控件,使用button-close.png作為其背景,并將字色設(shè)置為白色,文案為“Close”。
然后在現(xiàn)有界面基礎(chǔ)上再添加一個Image View,大致尺寸和位置如下圖所示:
切換至輔助編輯器模式,在新添加的空白Image View上執(zhí)行Control+拖拽,并指向BigImageViewController.h代碼當(dāng)中@interface與@end之間的部分,以此 方法分別建立名為“imageFrame”的Outlet,以及名為“closeView”的Action。系統(tǒng)將在.h文件中自動添加如下代碼:
而具體的closeView代碼還需要我們手動添加到.m文件當(dāng)中:
這段代碼的作用是關(guān)閉當(dāng)前已經(jīng)激活的模態(tài)視圖界面。
加載模態(tài)界面的代碼
回到標(biāo)準(zhǔn)編輯器模式,打開PortfolioViewController.h文件,將代碼手動更新為:
我們新寫了一行#import代碼,用來將之前新建的BigImageViewController類引入到 PortfolioViewController當(dāng)中,這樣我們就可以在Portfolio界面中與之通訊,在需要的時候告訴 BigImageViewController為自己創(chuàng)建一個實例。
我們還為PortfolioViewController創(chuàng)建了一個屬性和兩個方法,其中第二個方法openBigImage并不需要與.xib文件中的任何控件建立關(guān)聯(lián),所以它的返回類型是“void”,而非“IBAction”。
你也許會覺得奇怪,為什么在這里創(chuàng)建屬性和方法的時候,我們沒有使用副主編輯模式,通過拖拽方法來實現(xiàn)。其實結(jié)果是相同的,只是我們在這里刻意使用手動編碼的方式來練習(xí)一下。所以接下來,我們還要到.m文件中手動輸入那些與“屬性合成”以及內(nèi)存釋放相關(guān)的代碼:
這次還真是輸入了不少東西,我們來看看這些代碼的作用是什么。
selectImage1方法為bigImage屬性指定了具體的圖片,即image1-big.png文件。同時該方法還調(diào)用執(zhí)行了openBigImageView方法。
在openBigImageView中,我們首先創(chuàng)建了一個BigImageViewController類的實例,并將其命名為 “bigImageView”。這個實例自身就是一個模態(tài)界面,它會以“翻轉(zhuǎn)(flip)”的動畫效果出現(xiàn),并將bigImage作為具體的圖片放到其 imageFrame容器當(dāng)中。
因為我們通過代碼手動為BigImageViewController的實例分配了內(nèi)存,所以我們還要在適當(dāng)?shù)臅r候?qū)⑦@部分內(nèi)存釋放。問題在于,我 們并不知道這些資源會被使用多久,因為大圖模態(tài)界面會打開多長時間是取決于用戶的。要解決這個問題,我們需要使用autorelease命令,它會告訴 iOS系統(tǒng)一直保持內(nèi)存資源的分配狀況,直到確認(rèn)“安全”的時候再進行釋放。
模態(tài)視圖的代碼綁定
現(xiàn)在我們需要將代碼綁定到XIB當(dāng)中的控件上。選擇PortfolioViewController.xib文件,點擊文檔結(jié)構(gòu)列表當(dāng)中的“File's Owner”,然后打開右側(cè)的連接檢查器(Connections inspector)。
在“Received Action”中,我們可以看到之前編寫的selectImage1方法,它的右側(cè)是一個圓環(huán)。點擊這個圓環(huán)并進行拖拽,一直拖到界面當(dāng)中的第一個縮略圖上面釋放,如下圖所示:
在彈出的列表當(dāng)中選擇“Touch Up Inside”事件。
試著運行一下我們的應(yīng)用叭,如果之前的工作沒有出現(xiàn)問題的話,現(xiàn)在我們應(yīng)該可以在Portfolio界面中點擊第一個縮略圖并查看相應(yīng)的大圖了。
接下來,你可以自己試著對另外三個縮略圖進行處理了。你需要創(chuàng)建selectImage2,selectImage3,selectImage4這 三個新的方法,不過對于openBigImage方法來說就不需要重復(fù)創(chuàng)建了,它是可以被共用的。另外你也可以嘗試為模態(tài)界面使用不同的動畫過渡效果,包括
UIModalTransitionStyleCoverVertical
UIModalTransitionStyleCrossDissolve
UIModalTransitionStyleFlipHorizontal
UIModalTransitionStylePartialCurl
如果你在這個過程中遇到麻煩,也可以打開模板包,在End Result路徑中找到最終完成版的文件進行參考。
總結(jié)
本文確實涵蓋了不少方面的內(nèi)容,從Xcode的界面介紹、基本操作,到在Interface Builder中創(chuàng)建界面,以及實際代碼的編寫。我們通過一個簡單而具有代表性的案例了解了iOS應(yīng)用開發(fā)當(dāng)中的一些關(guān)鍵概念,包括類、屬性、方法、內(nèi)存管理等。
本文只是引領(lǐng)你入門的一個小小的起點。在此基礎(chǔ)上,你可以通過更多的資源進一步深入學(xué)習(xí)iOS開發(fā)的相關(guān)知識與技能了。好運!