To the user,the interface is the product.
-
Aza Raskin
iOS9帶來了許多新的特性來讓我們的開發生涯更簡單,Stack Views的簡介就是一個很好的例子.之前給你們簡單的介紹了auto layout.這個例子讓我們工作起來很簡單.但是,隨著你的app UI變得更復雜,你會發現給所有的iOS設備完美的提供界面約束變得更難.這是蘋果在最新的Xcode和Ios版本中介紹Stack views的一個原因.
這一章,我們將繼續討論界面編輯器里的UI設計.我會教你們怎么來構建一個更全面的界面,你可能會在實際運用中遇到的應用.你將學到如何:
使用堆棧視圖來布局用戶界面.
使用圖片視圖來顯示圖片.
使用內置目錄來管理圖片.
使用Size類調整堆棧視圖.
我們將根據上面的來討論更多的關于自動布局的內容.你可能會被嚇到,因為你一行代碼都沒寫卻可以干那么多的事.
堆棧視圖(Stack Views)是什么
先說重要的,什么是堆棧視圖?堆棧視圖提供一個流線型的界面來把視圖集合放置成一行或者一列.在Keynote或者PPT里,你可以把很多對象一起分組,那樣它們可以作為一個單獨對象移動或分組.堆棧視圖提供了一個非常相似的特性.你可以用堆棧視圖將很多UI對象合成一個.最好的是,視圖嵌入一個堆棧視圖里以后,你不再需要定義自動布局約束.
視圖嵌入一個堆棧視圖里時,他們通常被看做安排好的視圖.
堆棧視圖管理它子視圖的布局,然后自動為你提供布局約束.這意味著子視圖已經準備好去適應不同的屏幕尺寸.此外,你可以嵌入一個堆棧視圖到另一個堆棧視圖來構建更復雜的用戶界面.聽起來很酷,對嗎?
不要誤解我.這并不意味著你行不需要處理自動布局.你仍然需要定義堆棧視圖的布局.它僅僅能夠節約你在創作每個UI元素的約束的時間,然后輕松的從布局里來添加/移除視圖.
Xcode7提供兩個來使用堆棧視圖.你可以從對象庫里抓起一個堆棧視圖(水平/垂直),然后放進storyboard里.然后你可以拖放視圖對象如labels,buttons,image views到堆棧視圖.另一個辦法,你可以用自動布局欄里的Stack選項.用這個方法,你可以簡單的選擇兩個或者更多的視圖對象,然后選擇Stack選項.界面編輯器將會嵌入這些對象到一個堆棧視圖,然后自動重新調整大小.如果你對于怎么使用一個堆棧視圖沒有頭緒,不要擔心.這章我們會繼續講解這兩個方法.繼續閱讀,一會你就會知道我的意思了.
簡單的app
來看看我們將要構建的demo app.我將展示給你們怎樣用堆棧視圖來布局一個下面這樣的用戶界面:
如果你不用堆棧視圖,你也可以制作同樣的UI.但是就像你希望看到的那樣,堆棧視圖完全改變了你布局用戶界面的方法.再說一次,這章沒有代碼.
創建一個新的工程
現在關掉Xcode然后創建一個新的Xcode工程.選擇Application(iOS下)>"Single View Application"點擊"Next".你可以像下面這樣簡單的填寫工程信息:
Product Name:StackViewDemo - 這是你的工程名字.
Organization Name:AppCoda - 這是你公司的名字
Organization Identifier: com.appcoda - 事實上這個域名寫反了.如果你有一個域名,你可以用你自己的域名*名字.否則,你可以用"com.appcoda"或者就填"edu.self".
Bundle Identifier: com.appcoda.StackViewDemo - 這是你app唯一的標志,用于提交app.你不需要填這個選項.Xcode會自動幫你生成.
language:Swift - 我們將用Swift來開發這個工程.
Devices: Universal - 選擇"Universal".通用app是為iPhone,iPod touch,和ipad設備優化過的單獨app.在這個demo,我們將設計一個用戶界面能運行在所有的設備上.
Use Core Data:[unchecked] - 不要選擇這個.這個簡單工程用不到Core Data.
Include Unit Tests:[unchecked] - 不要選擇這個.這個簡單工程用不到單元測試.
Include UI Tests:[unchecked] - 不要選擇這個.這個簡單工程用不到UI測試.
點擊"Next".Xcode會問你準備把StackViewDemo工程保存在哪里.在你的mac上選擇一個文件夾.點擊"Create".
添加圖片到Xcode工程
像你看到的那樣,這個樣本app包含3張圖片.問題來了,怎樣才能在Xcode工程里綁定圖片?
在每個Xcode工程,它包括一個asset目錄(如Assets.xcassets)來管理圖片和圖標,這些會在你的app里用到.選擇Assets.xcassets文件夾.默認情況下,里面是空的,只有一個空白的AppIcon設置.我們在這章不準備討論app圖標,但是在我們構建了一個真正的app以后我們會說到它.
現在下載這些圖片設置然后解壓到你的Mac上.壓縮包里包含總共9張圖片文件,但是它實際上包含3個不同的t-shirt圖片.他們每一個都有3個不同的分辨率.這里有個例子:
t-shirt-1.png
t-shirt-1@2x.png
t-shirt-1@3x.png
當開發一個iOS app時,建議一章圖片準備3個版本.一個用@3x后綴,這個有最高的分辨率,用于iPhone 6 Plus.一個用@2x后綴,用于iPhone4/4s/5/5s/6,沒有@后綴是為非Retina屏幕用的.
添加這些圖片到asset目錄,你所要做的就是從Finder里拖拽圖片到設置列表
一旦你添加了圖片到asset目錄,圖片會自動設置.之后,如果要用這些圖片,你只要用一個特殊的名字(如t-shirt-1).你不需要擔心要用哪個版本(@2x/@3x).這些iOS都會幫你處理好.
用Stack Views布局標題標簽
現在你已經在工程中綁定好了必要的圖片,我們來看看堆棧視圖.首先,打開Main.storyboard.我們從這兩個詞開始.
堆棧視圖可以在垂直方向和水平方向安排多個視圖布局.所以首先,你需要決定你是否想要使用一個水平或者垂直的視圖.標題和副標題都被排成垂直的.顯然,我們將用一個垂直的堆棧視圖.
從對象庫里拉一個Vertical Stack View對象到storyboard里的view controller.
接下來,從對象庫里拉一個label放進堆棧視圖里.堆棧視圖會自動嵌入label,調整它的大小.雙擊label然后把標題改成"Wardrobe".在Attributes inspector里,把字體大小改成50.
編輯新標簽的標題然后改成"Keep your wardrobe organized".
一般來說,"Wardrobe"標簽是左對齊的.一旦有stack view,你可以批量改變很多stack view的屬性來改變它的顯示形式.選擇stack view然后你會發現它在Attributes inspector里的屬性.
順便說一聲,如果你選擇堆棧視圖有問題,你可以按住shift鍵然后右擊stack view.界面編輯器會顯示一個快捷菜單來讓你選擇.
我們簡要討論一下stack view的每個屬性.axis選項表明視圖要水平還是垂直布局.把它從vertical變成horizontal,你可以把現有的stack view變成垂直的stack view.alignment選項控制視圖怎樣對齊.例如,如果它設置成Leading,stack view會邊緣對齊(如左對齊).distribution選項定義視圖的大小和位置.默認情況下設置成Fill.在這個例子里,stack view視圖填滿子視圖的所有可用空間.如果設置成Fill Equally,垂直stack view會沿著垂直軸線平分兩個標簽.下圖顯示了一些不同屬性布局的例子.
在我們的demo中,僅僅需要改變alignment選項從Fill到Center,把兩個標簽居中.去下一節之前,確保你的stack view的位置是正確的.你可以選擇stack view去到Size inspector.確保你設置X的值為183,Y的值為46.
用水平stack view布局圖片
現在我們繼續T-shirt圖片.這些圖片是水平的,我們用水平的stack views替換.從對象庫里拖曳一個水平的stack view到storyboard里.在iOS,我們用image views來顯示圖片.從對象庫里尋找image view對象,把它拖進我們剛添加的stack view.重復這個步驟來添加另外兩個image views.如果你添加更多的image views到stack view里,它會自動水平的排列image views.
image view里還沒分配任何圖片.選擇左邊的image view然后去Attributes inspector.我們已經添加的T-shirt圖片到工程里,image選項自動從asset目錄讀取圖片.點擊image選項的下拉菜單選擇"t-shirt-1".重復同樣的步驟添加其他的image views.你的界面應該看起來像這樣:
確保你stack view的位置在X=20 Y=142.選擇stack view并且改變它的描述,從Fill變到Fill Equally.設置間隔為10.這會增加在image views之前增加一些空格.
Quick note:看起來stack view已經平分了image view.為什么我們要把屬性改變成Fill Equally?記得你現在是在一塊自由的畫布上設計UI.如果你不明確的把屬性設置成Fill Equally,iOS將用Fill分布方案布局image views.它可能在其它設備的屏幕上看起來不那么好
UI現在看起來不錯,對嗎?如果你運行app或者在界面編輯器里預覽UI,它看起來不像預料的那樣.因為我們還沒給stack views定義布局約束.你仍然需要為stack views創造布局約束.
為stack views添加布局約束
我們將定義下面的界面約束給stack view的標題:
在它和top layout guide之間設置一個隔斷約束.
把它水平居中.
從stack view里按住control拖曳到container view.按住shift鍵,選擇"Vertical Spacing to Top Layout Guide"和""Center Horizontally in Container".點擊Return來添加約束.
當stack view包含image view時,我們將定義以下的布局約束:
在它和其它stack view之間設置一個邊距約束,因此他們之間有個邊距.
在stack view左邊和視圖的左邊界之間設置一個邊距約束,在他們之間沒有空間(即0點).
在stack view右邊和視圖的右邊界之間設置一個邊距約束,在他們之間沒有空間(即0點).
現在在布局按鈕里點擊Pin按鈕.設置頂部,左邊和右邊的邊距約束分別為15.5,0和0
在模擬器中運行app,布局比之前的版本要更好看了.但是所有的圖片顯示都拉伸了.
事實上,stack view的高度被修復了,同時寬度發生了變化.因為實際的iPhone屏幕寬度比畫布的寬度要小,這是為什么圖片顯得被拉長了.
為了修復這個問題,我們應該定義更多的約束然后告訴stack view保持縱橫比,不用管屏幕的尺寸.在文檔概要視圖里,按住control拖曳stack view(包含image views).在快捷菜單里,選擇"Aspect Ratio".
再次運行project.布局應該看起來很不錯.
用stack view布局按鈕
讓我們繼續布局屏幕底部的兩個按鈕.在這段課程的最開始,我提到過有兩個方法來使用stack views.前面,你們從對象庫里添加了一個stack view.現在我將展示另一種方法.
首先,從對象庫里拖曳一個按鈕到視圖.雙擊按鈕把它命名為"Sign in".在Attributes inspector里,把它的背景色改成紅色,文本顏色改成白色.在Size inspector里,設置寬度(width)為200.
下一步,把另一個按鈕拖到視圖并且把它命名為"Sign up with email".在Attributes inspector里,把它的背景色改成紅色,文本顏色改成白色.在Size inspector里,設置寬度(width)為200.設置好以后,會顯示紅色的實線.
再說一次,你不需要為這些標簽設置布局約束.讓stack view為你變個魔法.按住command鍵來選擇兩個按鈕,然后點擊layout欄里的Stack按鈕.界面編輯器會自動嵌入他們到一個垂直stack view里.選擇stack view給兩個按鈕增加一個間隔.在Attributes inspector之下,設置間隔值為10.試著讓stack view垂直和水平居中.
同理,我們給這個stack view定義布局約束來讓它的位置靠近視圖的底部.這些是我們準備定義的布局約束:
讓stack view水平居中,
設置一個間隔約束來讓stack view和Bottom Layout Guide之間有個間隔.
你可以跟隨下面的圖例來增加約束.
有一件事你可能注意到,按鈕比我們希望的要小.當你嵌入按鈕到stack view時,他們被重新調整大小.如果你像設置寬度為200,你需要添加一個寬度約束到stack view.在文檔視圖里,按住control然后拖曳stack view到它自己然后選擇寬度來增加約束.
為了改變寬度為200點,在文檔概覽視圖里選擇寬度約束.然后到Size inspector,將constant改成200.stack view現在寬度修復成200點.
再測試一下app.在iPhone(或者ipad)上運行這個工程.你的UI應該看起來像下面這樣
用Size Classes調整stack views
如果你換個方式運行iPhone模擬器,UI在風景模式下看起來是這樣:
它工作得很好.我們來讓它看起來更好.我想要改變Top Layout Guide和標題的間隔,同樣的,標題和圖片的間隔也要改變.但是請注意這些改變僅僅只用提供給風景模式(橫屏)下的iPhone.
像你知道的那樣,我們可以通過改變間隔約束的量來調整間隔.真正的問題在于:我怎樣才能只調整iPhone的風景模式(橫屏)?
這里帶來一個新的設計概念叫做自適應布局(Adaptive Layout),這是iOS8發布的時候引進的.用自適應布局,你的apps能夠讓他們的UI來適應一個特殊的設備和設備方向.為了實現自適應布局,蘋果介紹了一個新的概念,叫做Size Classes.這可能是實現自適應布局最重要的方面.Size classes是一個抽象概念,說明了一個設備是怎樣依靠它的屏幕尺寸和方向來分類的.
一個size class為縱向(高)和橫向(寬)尺寸標識了一個顯示空間的相對數量.size classes有兩種類型:regular和compact.一個regular size class代表了大部分屏幕空間,同時compact size class代表了小部分屏幕空間.通過使用一個size class來描述每個顯示尺寸,這將會出現4種結果:Regular width-Regular Height,Regular width-Compact Height,Compact width-Regular Height,Compact width-Compact Height.
下面的表格顯示了iOS設備和他們正確的size classes:
為了表現一個顯示環境,你需要指定一個橫向的size class和一個縱向的size class.比如,iPad有固定的橫向size class和固定的縱向size class.在我們的例子里,我們要給iPhone提供特殊的風景模式布局.換句話說,這里我們要處理兩個size classes:
Compact width-Compact Height
Regular width-Compact Height
現在回到Main.storyboard.選擇Top Layout Guide和stack view的間距約束.在Size inspector里,點擊Constant選項邊上的+按鈕.選擇Any Width>Compact heigt,然后設置尺寸值為0.
Quick note: 這里,任何width包括compact和regular width
做完那些之后,當你的iPhone橫過來的時候,stack view和Top Layout Guide之間的間距將減到最小.在不同的iOS設備上運行這個工程然后看看結果.
你可以做同樣的步驟來調整標題和圖片的間距.我把這個留下來給你當練習.
你的練習
為了幫助你更好的理解size classes是怎樣工作的,我們來做另外一個簡單的例子.要求你創建專門為iPad設備創建另外一個布局.請在iPad上放置水平的按鈕來代替橫向的stack view來布局Sign in/Sign up按鈕.