Swift自適應布局(Adaptive Layout)教程(一)

通用的Storyboard

通用的stroyboard文件是通向自適應布局光明大道的第一步。在一個storyboard文件中適配iPad和iPhone的布局在iOS8中已不再是夢想。我們不必再為不同尺寸的Apple移動設備創建不同的storyboard文件,不用再苦逼的同步若干個storyboard文件中的內容。這真是一件美好的事情。

我們打開Xcode,新建一個項目:

圖片
圖片

選擇iOS\Application\Single View Application創建一個單視圖應用:

圖片
圖片

設置項目名稱AdaptiveWeather,語言選擇Swift,設備選擇Universal

圖片
圖片

創建好項目后,我們在項目目錄結構中可以看到只存在一個storyboard文件:

圖片
圖片

Main.storyboard文件就是一個通用的storyboard文件,它可以適配目前所有屏幕尺寸的Apple移動設備。打開該文件,同學們會看到一個View Controller,以及一個我們不太熟悉的界面尺寸:

圖片
圖片

同學們不要吃驚,沒錯,你們看到的就是一個簡單的、有點大的正方形!大伙都知道,在上一個版本的Xcode中,storyboard里的屏幕尺寸都對應著我們所選的目標設備的尺寸,但是這樣無法讓我們達到“用一個storyboard搞定所有設備”的宏偉目標。所以在iOS8中,Apple將storyboard中屏幕的尺寸進行了抽象處理,也就是說我們看到的這個正方形是一個抽象的屏幕尺寸。

我們接著往下走,選中Main.storyboard文件,然后在右側工具欄中選擇File Inspector頁簽,然后勾選Use Size Classes選項:

圖片
圖片

在新的iOS8項目中,該選項默認是勾選的。但當你使用老版本的項目創建新的storyboard文件時就需要你手動進行勾選了。

設置你的Storyboard文件

首先,我們打開Main.storyboard文件,從組件庫(Object Library)中選擇Image View拖拽到View Controller中。選中剛剛拖入的Image View,在右側工具欄選擇Size Inspector頁簽,設置X坐標為150,Y坐標為20,為300,為265。

然后再拖入一個View組件,設置X坐標為150,Y坐標為315,為300,為265。

選擇你剛才拖入的View,在右側工具欄中選擇Identity Inspector頁簽,在Document面板中的Label屬性輸入框中輸入TextContainer。這個屬性的作用就是給View起一個名字,方便我們辨認。這里要注意一下,Document面板有可能是隱藏的,我們需要點擊它后面的 Show按鈕來顯示它。我們拖入的這個View最后是顯示城市和溫度Label的容器。

圖片
圖片

完成上面的設置后,同學們可能會發現剛才拖入的View貌似看不到,這是因為它的背景色和View Controller的背景色是相同的,都是白色,所以我們不太容易辨別。我們來解決這個問題,選中View Controller的View,然后在右側工具欄中選擇Attribute Inspector頁簽,設置背景色為 紅:74,綠:171,藍:247。然后再選擇TextContainer,就是我們拖入的View,設置背景色為 紅:55,綠:128,藍:186。此時Main.storyboard文件中應該是這番景象:

圖片
圖片

到目前為止,我們在View Controller中添加了兩個組件Image View和View,這也是僅有的兩個組件,接下來我們就要給它們添加一些布局約束了。

添加布局約束

選擇image view,點擊底部自動布局工具欄中的Align按鈕,勾選Horizontal Center in Container選項,將后面的值設置為0,點擊 Add 1 Constraint按鈕添加第一個約束。

圖片
圖片

這個約束的意思是讓image view在它的容器(View Controller的View)中保持居中。

然后再點擊底部自動布局工具欄中的Pin按鈕,添加一個image view頂部與容器頂部間距的約束,我們設置為0:

圖片
圖片

上面這兩個約束使image view處于容器居中的位置,并且它的頂部與容器頂部有一個固定的間距?,F在我們需要添加image view和text container view之間的約束。同學們先選中image view,然后按住Ctrl鍵和鼠標左鍵,從image view往text container view移動鼠標:

圖片
圖片

松開鼠標左鍵后會彈出一個約束菜單,我們選擇Vertical Spacing

圖片
圖片

這個約束決定了image view底部和text container view頂部之間的距離。

現在選中image view然后點擊右側工具欄中的Size Inspector頁簽,同學們會發現這里在Xcode6中和之前的Xcode版本有所不同:

圖片
圖片

你會看到之前添加的三個布局約束,你可以在Size Inspector中很方便的修改這些布局約束。比如點擊Bottom Space To: TextContainer約束后的 Edit按鈕,會彈出約束屬性編輯框,我們讓Constant的值等于20:

圖片
圖片

然后點擊該彈出框之外的任意地方關閉該彈出框。

你先已經將TextContainer view頂部與image view底部的間距調整到了20,我們還需要添加TextContainer view另外三個邊的間距約束。

繼續選擇TextContainer view,點擊底部的Pin按鈕彈出 Add New Constraints窗口,在 Spacing to nearest neighbor面板中設置左、右、底部的約束,將值設置為0,然后點擊Add 3 Constraints按鈕添加約束。這里要注意的是,在設置約束時要將 Constrain to margins選項的勾去掉,這樣可以避免TextContainer view產生內邊距:

圖片
圖片

這三個約束會讓TextContainer view的左、右、底部三個邊與容器的左、右、底部的間距始終為0。

現在Main.storyboard中應該是這番景象:

圖片
圖片

此時同學們應該會注意到在view上有幾個橘黃色的約束線,這意味著還有一些約束上的問題需要我們注意。不過在運行時storyboard會自動更新view的大小來滿足它與容器的約束條件。我們也可以點擊底部 Resolve Auto Layout Issues 按鈕,在彈出框中選擇 All Views in View Controller/Update Frames 來修復提示的約束問題,但是如果我們這樣做,那么image view的尺寸就會壓縮成零,也就是會看不到image view。

這是因為我們的image view還有沒有任何內容,但是它有一個缺省的高和寬,并且值為0。進行自動布局的時候,如果被約束的view沒有實際的高和寬,那么會依照缺省的高和寬來滿足約束條件。

我們接著學習,在項目結構中打開 Images.xcassets ,然后點擊左下角的 +號,在彈出菜單中選擇 New Image Set

圖片
圖片

雙擊左上角的 Image 標題將其改為 cloud

圖片
圖片

我們剛才新建的這個image set其實就是若干圖片文件的一個集合,其中的每一個圖片都會對應一個特定的應用場景,也就是針對與不同分辨率的Apple移動設備。比如說,一個圖片集合可能會包含針對非視網膜、視網膜、視網膜高清三種分辨率的圖片。自從Xcode中的資源庫與UIKit完美結合后,在代碼中引入圖片時我們只需要寫圖片的名稱,程序在運行時會根據當前運行的設備自動選擇對應分辨率的圖片。

注意:如果你以前使用過通過資源庫管理圖片,那么你可能會發現在Xcode6中會有所不同。那就是3x圖片是怎么回事?

這個新的分片率是專為iPhone 6 Plus提供的。這意味著每一個點是由3個像素點組成,也就是說3x的圖片比1x圖片的像素多9倍。

目前你的圖片集合中還是空的,同學們可以在這里下載需要的圖片cloud_images.zip ,然后將圖片拖入剛才創建的名為cloud的圖片集合中,將 cloud_small.png圖片拖到 1x圖片區域:

圖片
圖片

由于我們的圖片背景顏色是透明的,所以在圖片集合中看到的都是白色的圖片。你可以選中某一個圖片,然后按下空格鍵來預覽圖片。比如選中 1x 圖片,按下空格:

圖片
圖片

現在將 cloud_small@2x.png 圖片拖至 2x 圖片區域,將 cloud_small@3x.png 圖片拖至 3x 圖片區域。和之前情況一樣,我們看到的只是白色的圖片,但我們可以通過空格鍵來預覽圖片集合中的圖片。

現在你就可以在image view中設置圖片了。我們回到 Main.storyboard 中,選中image view,在右側工具欄中選擇 Attribute Inspector 頁簽,將 Image View 面板中的 Image 屬性設置為 cloud,然后將 View 面板中的 Mode 屬性設置為 Aspect Fit

圖片
圖片

現在你的Main.storyboard中應該是這番景象:

圖片
圖片

我們看到storyboard中一直有橘黃色的約束提示,是時候讓我們來修復它們了。首先選中view controller的view:

圖片
圖片

然后點擊底部的 Resolve Auto Layout Issues 按鈕,在彈出菜單的 All Views in View Controller 面板中選擇 Update Frames

圖片
圖片

這時,storyboard會自動根據約束條件重新計算view的大小以滿足約束:

圖片
圖片

預覽助手編輯器(Preview Assistant Editor)

一般情況下,在這個時候我們應該會在iPad、iPhone4s、iPhone5s、iPhone6、iPhone6 Plus這幾個不同尺寸的設備上編譯運行程序,以便測試通用的storyboard是否能在不同尺寸的設備上正確的自適應。但這確實是個體力活,一遍一遍的更改設備、編譯、運行,多么苦逼。但上天總是會眷顧我們這些苦逼的程序員,Xcode6提供了Preview Assistant Editor,能在一個界面上顯示出不同尺寸設備的程序運行情況,是否有問題一目了然。

我們打開 Main.storyboard ,然后選擇 View\Assistant Editor\Show Assistant Editor ,這時編輯區會分隔為兩部分。再點擊頂部導航欄中的 Automatic ,在彈出菜單中選擇 Preview ,最后選擇 Main.storyboard (Preview)

圖片
圖片

現在在 Assistant Editor 區域會顯示一個4寸的界面:

圖片
圖片

我們還可以點擊預覽界面底部,名字(比如圖中的iPhone 4-inch)旁邊的地方讓屏幕翻轉為橫屏:

圖片
圖片

這無疑是針對檢查不同尺寸設備的自適應情況的一項重大改進,但還遠遠不止于此!點擊預覽界面左下角的 + 按鈕,會彈出當前storyboard文件支持的各種尺寸的設備,可供我們預覽:

圖片
圖片

分別選擇iPhone 5.5-inch和iPad,此時我們在預覽界面就可以同時顯示三種尺寸的屏幕:

圖片
圖片

此時同學們是否注意到4寸的橫屏顯示有點別扭呢?沒錯,它的那朵元太大了,我們可以通過對image view添加其他的約束條件來改善這個問題。

回到 Main.storyboard ,選擇image view,然后按住 Ctrl建和鼠標左鍵,拖動鼠標到View Controller的View上,松開鼠標后會彈出一個菜單,我們選擇 Equal Heights

圖片
圖片

這時會出現一些紅色的約束提示,這是因為我們剛才加的這個約束條件與之前加過的約束條件有沖突。因為之前我們添加過image view和TextContainer view之間的垂直間距(Vertical Margins)約束,所以image view的高度不可能等于它容器(View Controller的View)的高度。

讓我們來修復該問題,首先在storyboard的結構目錄中選擇我們剛才添加的 Equal Heights 約束,然后選擇右側工具欄中的 Attribute Inspect 頁簽,如果 First Item 屬性不是 cloud.Height ,那么在下拉菜單中選擇 Reverse First and Second Item 這一項讓 First Item 的值成為 cloud.Height

圖片
圖片

接下來將 Relation 屬性的值設置為 Less Than or Equal ,將 Multiplier 的值設置為 0.4

圖片
圖片

這一系列設置的作用是讓cloud這張圖片的高度要么等于它自身的高度,要么等于屏幕高度的40%,最后呈現的效果選擇這兩者中較小的一個高度。

現在你應該注意到了在預覽面板中,4寸的橫屏顯示即時的對你剛才的約束改動做出了響應:

圖片
圖片

你看看其他尺寸的預覽自動更新了么?答案那是必須的,所以說 Preview Assistant Editor 確實是一項重大改進,是程序員和設計人員的福音!

由于本文的示例是一個天氣應用,所以光有天氣圖標不行,我們還得加上城市和溫度才行。

本文首發地址:Swift自適應布局(Adaptive Layout)教程(一)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容

  • 原文:http://www.raywenderlich.com/113768/adaptive-layout-tu...
    kitty123閱讀 3,556評論 2 3
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,802評論 18 139
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,155評論 4 61
  • 從我記事起,媽媽沒有留過長發。 年輕時候她的頭發又粗又長,她抱著我喂奶的時候,我的小手總是抓著她的頭發玩。周歲的時...
    lichangan閱讀 699評論 0 0
  • 硝煙迷迭,熏浸消逝的瞳眸。 逆亂的霸血,郁留晉陽的腥膻。 一騎絕塵,藉含幽幽蠻血; 昭陵六駿,紛踏昏隋嚎喪。 狂殤...
    Rain堯宇閱讀 340評論 0 0