這篇教程的前半部分被翻譯出來很久了,我也是通過這個(gè)教程學(xué)會的IOS自動(dòng)布局。但是后半部分(即本篇)一直未有翻譯,正好最近跳坑翻譯,就尋來這篇教程,進(jìn)行翻譯。前半部分已經(jīng)轉(zhuǎn)載至本博客,后半部分即本篇。學(xué)習(xí)IOS自動(dòng)布局的朋友可以看看。自動(dòng)布局很強(qiáng)大。
轉(zhuǎn)載請注明來源:http://m.survivalescaperooms.com/zer0Black/p/3977288.html
作者:zer0Black
這篇教程絕對的最好的學(xué)習(xí)IOS自動(dòng)布局的文章,沒有之一
原文地址:Beginning Auto Layout Tutorial in iOS 7: Part 2
正文如下:
請注意: 團(tuán)隊(duì)成員Matthijs Hollemans (IOS學(xué)徒系列的作者) 已經(jīng)將這篇教程移植到iOS 7 feast. 我們希望您喜歡!
在開始iOS 7中自動(dòng)布局教程(一) 你已經(jīng)看到舊的“struts-and-sPRings”模型讓user interfaces不能較容易的解決所有的布局問題。自動(dòng)布局是一個(gè)解決方案,但是也是因?yàn)樗膹?qiáng)大,所以在使用它的時(shí)候,我們需要一點(diǎn)小技巧。
值得高興的是,Xcode5讓自動(dòng)布局更容易了。如果你在Xcode4中嘗試過自動(dòng)布局并且放棄了,那現(xiàn)在我們希望你能再給它一個(gè)機(jī)會。我們將在Xcode5中使用它。
在第二部分和最后一部分自動(dòng)布局的系列教程中,你將要繼續(xù)學(xué)習(xí)所有關(guān)于約束的知識以及如何應(yīng)用它們。
這個(gè)自動(dòng)布局的教程將從下面這個(gè)非常簡單的app開始:
app中有兩個(gè)設(shè)置了背景色的按鈕,你可以更清楚的看到它們的邊界。它們之間有一些約束。如果你學(xué)習(xí)的上一部分,你可以繼續(xù)使用你之前的app,只要你移除界面上的其它兩個(gè)按鈕。
如果你打算重新開始,請使用Single View application模板創(chuàng)建一個(gè)新的iphone應(yīng)用。拖兩個(gè)按鈕到場景中并且給它們設(shè)置背景顏色。使用Editor/Pin菜單在兩個(gè)按鈕之間創(chuàng)建一個(gè)Vertical Spacing約束,然后靠下的按鈕創(chuàng)建一個(gè)Bottom Space to Superview約束(大小為20點(diǎn))。使用Editor/Align菜單給黃色按鈕創(chuàng)建一個(gè)橫向居中的約束,然后兩個(gè)按鈕align the left edges(對齊左邊緣)。
在Interface Builder中執(zhí)行,一切看起來都很棒。但是讓我們看看它們是怎么工作的。在ViewController.m中加入下面的方法:
- (IBAction)buttonTapped:(UIButton *)sender{ if ([[sender titleForState:UIControlStateNormal] isEqualToString:@"X"]) { [sender setTitle:@"A very long title for this button" forState:UIControlStateNormal]; } else { [sender setTitle:@"X" forState:UIControlStateNormal]; }}給長標(biāo)題和短標(biāo)題按鈕都設(shè)置單擊觸發(fā)事件。在Interface Builder中將按鈕都連接到action方法上。按住ctrl拖拽每個(gè)按鈕到view controller并且在彈出窗中選擇buttonTapped。
運(yùn)行這個(gè)app并且單擊按鈕,看看它是怎么變化的。可以在橫屏和豎屏都進(jìn)行測試。

不管按鈕是長標(biāo)題還是短標(biāo)題,布局總是被安全的約束著:
上面三點(diǎn)就是你的user interface中所顯示的全部說明
讓我們來試試,移除左對齊約束(在outline窗口中選擇并且按下Delete鍵),然后選中在Interface Builder里的所有按鈕,在對齊菜單中選擇對齊右邊緣。現(xiàn)在再次運(yùn)行你的app觀察與之前的區(qū)別。
我們再來一次,這次選擇Align/Horizontal Centers。它將使兩個(gè)按鈕總是居中對齊。運(yùn)行app,點(diǎn)擊按鈕,看看它們是怎么運(yùn)行的。(記住,如果你改變約束時(shí)看到了橘黃色的虛線矩形,你可以使用 Editor/Resolve Auto Layout Issuesmenu來更新按鈕的大小和位置。)
Pin菜單有一個(gè)選項(xiàng)是Widths Equally。如果你在兩個(gè)view中設(shè)置了這個(gè)約束,自動(dòng)布局將總是讓所有view的寬度等同于最大的那個(gè)view的寬度,讓我們來試試。
選中所有按鈕,并且選擇Editor/Pin/Widths Equally。這就給所有按鈕都加上了一個(gè)新約束:

在這之前,你可以先看看教程第一部分的關(guān)于約束類型的內(nèi)容。它看起來就像一個(gè)T字架,但在中間有一個(gè)寫著“=”號的圓。
當(dāng)然,也許是兩個(gè)T字架,在Outline文檔中顯示了一個(gè)單獨(dú)的Equal Widths約束:

改變按鈕上的label文本,兩個(gè)按鈕的尺寸都會同時(shí)改變。將下面的按鈕的label文本改為“X”。這時(shí)候,你會發(fā)現(xiàn)上面的按鈕,不能再匹配它的文本了:

那自動(dòng)布局是怎么知道使用哪個(gè)按鈕的寬度呢?如果你留心一點(diǎn),你可能注意到上面的按鈕的尺寸不再正確了:

顯然這不是你想要的效果,選擇上面的按鈕并選擇Size to Fit Content從Editor菜單中(或使用快捷鍵 ? =)。現(xiàn)在,文本再次匹配按鈕了,并且因?yàn)镋qual Widths約束的原因,黃色按鈕也改變了尺寸。
運(yùn)行app并且單擊按鈕,這個(gè)按鈕現(xiàn)在總是一樣寬了,不管哪一個(gè)label更大:

當(dāng)然,如果label都非常短,按鈕都會等寬收縮。除非有其他約束阻止了,否則按鈕尺寸將會精確的匹配它們的標(biāo)題,不多,不少。我們怎么稱呼這種情況?對的,就是固有內(nèi)容大小。
固有內(nèi)容大小
在有自動(dòng)布局之前,你總是需要告訴按鈕和其他的控件它們應(yīng)該有多大,然后設(shè)置它們的frame或bounds,再或者在Interface Builder里恢復(fù)它們的尺寸。但是現(xiàn)在情況改變了。大多數(shù)控件完全可以根據(jù)內(nèi)容來決定它們到底需要多寬。標(biāo)簽可以知道自己有多寬多高,因?yàn)樗牢谋镜拈L度和文字的大小。按鈕也一樣,可以根據(jù)文本,背景圖和內(nèi)邊距等來決定大小。同樣的,這對于segmented controls, progress bars和其他大多數(shù)的控件也都是有效的,不過可能其中有一些控件只能預(yù)判高度而不能知道它的寬度。這種特性被叫做固有內(nèi)容大小,它對于自動(dòng)布局是一個(gè)很重要的概念。你已經(jīng)見過button的action了。自動(dòng)布局會詢問你的控件需要多大,并且會依據(jù)那些信息在屏幕上把控件畫出來。通常情況下,你都會使用固有內(nèi)容大小,但也有一些特殊情況你不想用它。那你就可以給控件設(shè)置一個(gè)準(zhǔn)確的Width和Height約束來阻止固有尺寸大小的使用。設(shè)想一下,你在UIImageView上設(shè)置了一張圖片,如果圖片的大小超出了屏幕,會發(fā)生什么?你可以給這個(gè)image view一個(gè)固定的寬高和縮放比例,除非你想重定義圖片的尺寸。
如果你給按鈕一個(gè)固定寬度的約束會發(fā)生什么?按鈕會計(jì)算自己的尺寸,但是如果你給了一個(gè)固定的尺寸,它就不會再計(jì)算。選擇靠上的按鈕并且選擇Pin/Widthfrom菜單。給按鈕添加一個(gè)固定寬度(在按鈕下方出現(xiàn)一個(gè)完整的T字架):

因?yàn)檫@種類型的約束只會對按鈕本身有效,對它的父視圖無效,所以在Outline文檔中,它將會列在按鈕對象下面,你可以固定這個(gè)按鈕的寬度為46點(diǎn)。
你不能簡單的拉伸按鈕來調(diào)整大小。如果你這么做了,你最后只會得到一個(gè)橘黃色的虛線框。一定要記住,在Xcode5中不會自動(dòng)更新約束(不像Xcode4)。因此,如果你改變了按鈕的尺寸和位置,他會提示你需要讓約束再次匹配。這是僅簡單的改變約束的一種替代方法。
選擇Width約束并進(jìn)入Attributes inspector選項(xiàng)卡。把按鈕的寬度約束改為80點(diǎn):

運(yùn)行app并點(diǎn)擊按鈕,發(fā)生了什么?按鈕的文本改變了,但是它被刪除了一部分,這是因?yàn)樵诎粹o中沒有足夠的空間:

因?yàn)榭可系陌粹o有一個(gè)fixed-width約束,并且所有的按鈕都要求一樣的尺寸,所有它們就永遠(yuǎn)不會收縮或者擴(kuò)展。
注意:你可能在設(shè)計(jì)中不想給按鈕設(shè)置Width約束,那最好的辦法就是讓按鈕使用固有尺寸,但是如果你遇到你想在app運(yùn)行時(shí)改變控件的尺寸,但是卻不能的情況。你就應(yīng)該仔細(xì)檢查一下是不是有fixed Width尺寸約束在作祟。
Play around with this stuff for a bit to get the hang of pinning and aligning views. Get a feel for it, (這句翻譯不了,自行解決~)不是一切都能立刻就顯而易見的,你只要記住必須有足夠的約束自動(dòng)布局才能預(yù)計(jì)算所有視圖的位置和尺寸。

你現(xiàn)在可能會想約束到底是什么,你要怎么樣才能通過建立不同視圖之間的關(guān)系,從而構(gòu)建起自己的布局。在下面一節(jié)中,你將看到怎么使用自動(dòng)布局和約束來創(chuàng)建一個(gè)符合真實(shí)世界場景的布局。
讓我們假裝你想做一個(gè)瀏覽你圖片的程序。它在橫屏和豎屏中看起來就像下面這樣:

屏幕被分成了4塊,每一塊都有一個(gè)image view和label。我們要怎么樣才能達(dá)到這種效果呢?
讓我們開始創(chuàng)作這個(gè)app吧。首先用Single View Application模板創(chuàng)建一個(gè)新的iphone項(xiàng)目,名字叫“Gallery”。
打開Main.storyboard。從Object Library中拖拽View到視圖上。把尺寸設(shè)置為160點(diǎn)和284點(diǎn),并且把它的背景色變?yōu)榘咨酝獾钠渌伾ɡ?綠色):

注意:拖拽UIView到故事板上有兩個(gè)原因:a)你要使用它來包含其他的控件視圖,這些控件可以幫助你組織起場景的內(nèi)容;b)它也作為一個(gè)自定義view或控制器的占位符,你可以設(shè)置它的Class屬性,將它變?yōu)槟阕远x的UIView/UIControl的類(即繼承UIView/UICtontrol的類)。
讓我們給這些view一點(diǎn)約束。你已經(jīng)看過加約束的兩種方式:用Editor/Pin和Align菜單,還有按住ctrl在兩個(gè)view之間拖拽。這里告訴你第三種添加約束的方法。在Interface Builder窗口的底部有一行這樣的按鈕:

橢圓包圍的四個(gè)按鈕就是用于自動(dòng)布局的。從左到右分別是:對其(Align),固定(Pin),解決自動(dòng)布局問題(Resolve Auto Layout Issues)和重定義尺寸(Resizing Behavior)。前三個(gè)按鈕魚Editor菜單中的對應(yīng)項(xiàng)有一致的功能。Resizing Behavior按鈕允許你在重新設(shè)置view的尺寸的時(shí)候,改變已經(jīng)添加的約束。
選擇綠色的view并且點(diǎn)擊Pin按鈕。會彈出一系列你可以添加的約束:

頂部的Spacing to nearest neighbor是最經(jīng)常用到的。點(diǎn)擊者4個(gè)T字架,它們就會變成實(shí)體的紅色:

這樣就會給綠色的view和它的父視圖的四邊創(chuàng)建四個(gè)新約束。實(shí)際上的間距值因人而異,這要看你view的位置。(你不需要改變這些值來匹配我的圖)。點(diǎn)擊 Click Add 4 Constraints完成約束的添加
現(xiàn)在你的故事板看起來應(yīng)該這樣:

視圖需要這4個(gè)約束來保證它的位置。UIView不像button或者label,它沒有固有內(nèi)容大小。你必須有足夠的約束來保證每個(gè)view的位置和尺寸,view總是需要約束來告訴它,它需要多大。
你可能會奇怪,尺寸的約束在哪?在這個(gè)案例中,view的尺寸約束是隱含在父視圖的尺寸中。布局中有兩個(gè)Horizontal Spaces約束和兩個(gè)Vertical Spaces約束,這樣就能保證固定的長度。你在Outline文檔中可以看到他們:

綠色view的寬是由這個(gè)公式計(jì)算出來的:“父視圖的寬-(98+62)”,它的高是:“父視圖的高-(65+199)”。這樣,間距就被固定了,你的view除了重新定義尺寸之外別無他法。(你的值可能會有所不同,它依據(jù)于你的view放的位置)。
當(dāng)你旋轉(zhuǎn)這個(gè)app的時(shí)候,父視圖的規(guī)格就會從320X568變?yōu)?68X320。公式就會重新計(jì)算寬和高,這時(shí)候你會得到新的綠色view的尺寸(408X56)。
你可以旋轉(zhuǎn)你自己的試試,你也可以在Interface Builder直觀的模擬它們。打開Assistant editor(按Xcode工具欄中看起來像 外星人/男管家 的那個(gè)按鈕)并且在彈出的菜單中選擇Preview:

單擊底部的箭頭按鈕可以改變界面的方向。這樣就能立刻給你一個(gè)橫屏的故事板布局預(yù)覽。綠色view會重定義尺寸以滿足橫向間距和縱向間距的約束。
你可以留下這個(gè)預(yù)覽窗口,當(dāng)你設(shè)計(jì)UI時(shí),它會自動(dòng)改變。你也可以在3.5吋和4吋屏之間切換。
注意:你可能會奇怪為什么頂部的約束沒有頂?shù)狡聊坏淖钌厦妫?/span>

而是停在了狀態(tài)欄處。這是因?yàn)樵趇os7中,狀態(tài)欄總是繪制在view控制器的頂部 - 而不再是一個(gè)單獨(dú)的bar。這樣做有什么用?當(dāng)你創(chuàng)建約束時(shí),它無法確切的依附在屏幕頂部,但是頂部會有一個(gè)看不見的行,它叫做 Top Layout Guide。
在一個(gè)正常的view控制器中,這個(gè)guide距頂部有20點(diǎn),至少在狀態(tài)欄不隱藏的時(shí)候是這樣的。在導(dǎo)航控制器中,它位于導(dǎo)航欄下面。因?yàn)閷?dǎo)航欄在視圖中有不一樣的高度, Top Layout Guide會在設(shè)備旋轉(zhuǎn)時(shí)隨著導(dǎo)航欄移動(dòng)。這樣就很容易的得到view和導(dǎo)航欄的相對位置。同樣的,底部也有Bottom Layout Guide,用來放置標(biāo)簽欄和工具欄。
有時(shí)候,可能你不想在設(shè)備旋轉(zhuǎn)時(shí)重設(shè)你的UIView的尺寸,因此你可以給這個(gè)view一個(gè)固定的寬高約束。現(xiàn)在,讓我們來試試。選擇綠色的view并點(diǎn)擊Pin按鈕;在彈出窗口中給width和height打上勾。

點(diǎn)擊Add 2 Constraints來完成約束的添加。現(xiàn)在你給視圖添加了兩個(gè)新約束,一個(gè)是寬度160點(diǎn)的約束,一個(gè)是高度284點(diǎn)的約束:

因?yàn)閷捄透邇H應(yīng)用在當(dāng)前視圖,所以它們在Outline文檔中位于自己的view下面。一般來說,約束都表達(dá)了兩個(gè)不同view之間的某種關(guān)系 - 例如:橫向間距和縱向間距(Horizontal and Vertical Space)約束就是綠色視圖與它父視圖的關(guān)系 - 你也可以認(rèn)為寬度和高度約束是綠色視圖和它自己的約束。
運(yùn)行app,噢,看起來多棒啊。現(xiàn)在把你的屏幕橫置,哎喲!沒有像你想的那樣 - 視圖的尺寸再次該變 - 而是報(bào)錯(cuò)了,Xcode給出了一堆錯(cuò)誤的信息:
Gallery[39367:a0b] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: |
你還記得我說過“必須有足夠的約束,自動(dòng)布局才能計(jì)算所有視圖的位置和尺寸”么?好吧,在這個(gè)例子中,約束又太多了。當(dāng)你看到“不能同時(shí)滿足所有約束(Unable to simultaneously satisfy constraints)”的錯(cuò)誤的時(shí)候,那就意味著你的約束之間有沖突。
讓我們再看一下哪些約束:

綠色視圖上設(shè)置了6個(gè)約束,4個(gè)間距約束(1-4)和你剛剛設(shè)置的寬高約束(5和6)。沖突在哪呢?
在豎屏的時(shí)候不應(yīng)該有問題,因?yàn)樵跀?shù)學(xué)上是滿足的。父視圖的寬是320點(diǎn)。如果你添加了Horizontal Space和Width約束,你應(yīng)該保證它們的總長度小于等于320點(diǎn)。這是我計(jì)算視圖位置的方式:98+160+62 = 320。同樣的,所有豎向約束相加以后就應(yīng)該是568點(diǎn)。
但是當(dāng)你旋轉(zhuǎn)設(shè)備為橫屏?xí)r,窗口(指的父視圖)就變成了568點(diǎn)寬。這意味著98+160+62+? = 568。這里額外多了248點(diǎn),無法滿足方程式,所以自動(dòng)布局不知道從哪里來得到這248點(diǎn)。同樣的,對于豎向約束也是一樣。
解決沖突的辦法有兩個(gè):第一是保持view的寬度固定,但外邊距必須可變。第二是保持外邊距固定,但寬度必須可變。你不能同時(shí)固定它們。你要去掉這些約束中的其中一個(gè)。在上面的例子中,若你想要在橫屏豎屏中都擁有同樣的寬,那Horizontal Space就必須去掉。
移除右邊的橫向間距和下邊豎向間距。故事板上會顯示成這樣:

好了,現(xiàn)在view就有一個(gè)正確約束來預(yù)判它的尺寸與位置了 - 不多,不少。運(yùn)行app來查證一下錯(cuò)誤信息是否已經(jīng)沒有了,然后這個(gè)view在旋轉(zhuǎn)以后是否能保持寬度。
注意:盡管Interface Builder可以很好的警告你有無效的約束,但它不是神。它只會警告你:噢,你的約束不夠。但是如果你約束太多了,它就無法檢測出來了。不過至少在出錯(cuò)的時(shí)候,自動(dòng)布局還是會給出一個(gè)詳細(xì)的錯(cuò)誤信息。如果你想要學(xué)習(xí)更多關(guān)于如何分析錯(cuò)誤信息和診斷布局問題,那你可以看 iOS 6 by Tutorials中的“Intermediate Auto Layout”。
拖拽一個(gè)label到綠色的view上。注意看,現(xiàn)在參考線出現(xiàn)在了綠色view的內(nèi)部,因?yàn)樗莑abel的父視圖。

調(diào)整label的位置到參考線的下邊距,橫向居中的地方。給label下面添加與綠色view之間的間距約束,有20點(diǎn)的距離。快速的方式是使用Pin按鈕,僅選擇下面的T字架:

現(xiàn)在給label添加橫向居中的約束。你已經(jīng)試過Editor/Align菜單了,但你也可以使用自動(dòng)布局菜單的Align按鈕。選擇label并點(diǎn)擊Align按鈕,得到一個(gè)彈出窗:

在Horizontal Center前打上勾然后點(diǎn)擊Add 1 Constraint。這時(shí)候,故事板應(yīng)該是這個(gè)樣子的:

注意這兩個(gè)新的橫向和縱向間距約束是位于綠色view自己的約束列表里,而不是在主視圖里。
拖拽一個(gè)新的Image View對象到故事板上,讓你的布局看起來像這樣::

這個(gè)圖片視圖固定了上,左,右邊緣在父視圖上,但下部以標(biāo)準(zhǔn)的8點(diǎn)間距連接在了label的頂部。如果你不確定要怎么做,那就跟著下面的步驟走:
1. 拖拽image view到綠色視圖中,現(xiàn)在不用擔(dān)心它的尺寸和位置:

2. 選中image view,按Pin按鈕選擇下面的選項(xiàng):

上,左,右的T字架設(shè)置為20點(diǎn),但是下面的設(shè)置為8點(diǎn)。重點(diǎn):對于Update Frames,你應(yīng)該選擇Items of New Constraints。如果你左邊距已經(jīng)默認(rèn)滿足要求,故事板看起來就是這樣的:

上面這個(gè)約束是你選擇了一個(gè)不一樣的frame。如果你選擇了Items of New Constraints, Interface Builder將自動(dòng)的調(diào)整畫面來添加約束,一切看起來都很棒:

當(dāng)然,如果你選錯(cuò)了frame,你也可以使用Resolve Auto Layout Issues button來修復(fù)它:

下載這個(gè)教程資源并解壓這個(gè)文件。你就會找到一個(gè)圖片文件夾 - 添加這個(gè)文件夾到你的項(xiàng)目。設(shè)置Ray.png作為這個(gè)image view的圖片,改變image view的模式為aspect Fit并且設(shè)置它的背景色為白色。把label的文本改為“Ray”。
你的布局應(yīng)該是這樣的:

你可能注意到綠色view內(nèi)部的約束突然變成了橘黃色。這發(fā)生在你給image view設(shè)置圖片的時(shí)候。你的布局為什么突然無效了?幸運(yùn)的是你可以帶著你的猜想來讓Xcode告訴你為什么錯(cuò)處了。
點(diǎn)擊這個(gè)這個(gè)紅色的靶子,它位于View控制器的Outline文檔中:

你會看到一個(gè)Content Priority Ambiguity(內(nèi)容優(yōu)先級歧義)的錯(cuò)誤。這意味著:如果image view和label都沒有固定的高度,那自動(dòng)布局系統(tǒng)就不知道應(yīng)該怎么分配大小。(Interface Builder似乎會忽略已經(jīng)設(shè)置過的固定高度約束)
讓我們把綠色的view的高度變?yōu)?00點(diǎn)試試。自動(dòng)布局是怎么將這100點(diǎn)分配給view內(nèi)部的label和image view的?是label保持尺寸而image view變成100點(diǎn)高了么?還是label變高了而image view保持尺寸?還是他們各自被分配了50點(diǎn),又或者劃分成25/75,40/60,又或者其它的什么結(jié)合?
如果你不解決這個(gè)問題,那么自動(dòng)布局系統(tǒng)就會去猜測,就可能導(dǎo)致結(jié)果莫名其妙。
恰當(dāng)?shù)慕鉀Q辦法是改變label的“Content Compression Resistance Priority”。你將從隨后內(nèi)容中學(xué)習(xí)到更多。現(xiàn)在,打開label的Size inspector,設(shè)置Content Compression Resistance Priority的vertical為751。這樣就使它的優(yōu)先級高于image view。然后繼續(xù)設(shè)置Content Hugging Priority為252。

這時(shí)候T字架就會再次變成藍(lán)色,自動(dòng)布局系統(tǒng)的警告也會消失。
拖拽綠色的view到主視圖的左上角。回憶一下之前做過的,綠色的view已經(jīng)有Horizontal Space和Vertical Space約束來控制它在父視圖中的位置了。現(xiàn)在,這些約束依然存在,它們導(dǎo)致了視圖的frame無法對齊參考線。

為了修正它,使用Resolve Auto Layout Issues按鈕并選擇Update Constraints。之前你使用的Update Frames,用來移動(dòng)和重定義view的尺寸來匹配你的約束。現(xiàn)在這剛好是一個(gè)相反的操作:你會用你的約束來匹配view的frame。
你可能注意到在頂部的Vertical Space現(xiàn)在是負(fù)的。這種情況是因?yàn)榧s束鏈接到了Top Layout Guide(頂部參考線)。不要問為什么,沒有規(guī)定說約束值不能是負(fù)的,你可以就像這樣留下它。(如果你看著礙眼,那就刪掉 “Vertical Space (-20)”約束,然后把view重新綁定到窗口的頂部)
Horizontal Space現(xiàn)在為0,表現(xiàn)為一條緊貼窗口左邊緣的粗藍(lán)線。盡管view已經(jīng)位于角落里了,但是它任然需要約束來固定住它:

選擇綠色的視圖按下?D來復(fù)制它。移動(dòng)復(fù)制的視圖到右上角:

注意T字架現(xiàn)在是橘黃色的。當(dāng)你復(fù)制它的時(shí)候,它已經(jīng)上丟失了X,Y坐標(biāo)的約束。為了修正它,固定view到窗口的右、上邊緣。
再復(fù)制兩次,分別把復(fù)制的視圖放在坐下角落和右下角落。然后再把他們固定在他們該在地方。
改變后的場景如下:

哈哈~他們看起來好像都是程序員 :-)
運(yùn)行app,在豎屏上很棒,但是橫屏上可能不是那么好:

本來應(yīng)該很棒的戰(zhàn)士卻變糟了:你給4個(gè)色彩鮮艷的容器view設(shè)定了固定的寬和高,因此它們就總是保證這樣的尺寸,而不管它們的父視圖的尺寸如何。
從這4個(gè)view下,選擇Width (160)和Height (284)的約束并刪除它們(在Outline文檔中很容易完成)。如果你現(xiàn)在運(yùn)行app,你會看到:

注意:如果你很奇怪為什么有的view變得比其他的大了,那我告訴你,這是固有內(nèi)容尺寸的原因。圖片的尺寸決定了image view有多大。文本的尺寸決定了label有多大。再加上四邊的20點(diǎn)外邊距,所有的尺寸加起來決定了每個(gè)視圖的尺寸。
這看起來很像你的上一部分解決的問題,因此你要向前思考,你可能回憶起來了,你要讓每個(gè)view的寬和高都相等。
選擇這4個(gè)view。Outline大綱里很容易完成;按住?點(diǎn)擊這4個(gè)view。你就可以添加這個(gè)約束。在彈出窗中,給Equal Widths和Equal Heights打上勾,然后點(diǎn)擊Add 6 Constraints。

再次運(yùn)行這個(gè)app并且旋轉(zhuǎn)設(shè)備。噢...還是不咋地:

所有的view都有同樣的高,并且他們也有同樣的寬,你的約束是對的。但這個(gè)寬和高可能不是你想要的。
光告訴自動(dòng)布局系統(tǒng)必須有同樣的尺寸是不夠的。因?yàn)樽詣?dòng)布局系統(tǒng)不知道這4個(gè)view是互相連接的。它們的邊貼邊的設(shè)計(jì),但在它們之間沒有這樣的約束。自動(dòng)布局就不知道它需要在“Ray”個(gè)“Matthijs”之間劃分窗口。
如果自動(dòng)布局系統(tǒng)自己不能完成,那你就要告訴它。

選擇Ray和Matthijs的視圖,從編輯菜單選擇Pin/Horizontal Spacing。因?yàn)関iew之間是邊貼邊的,那在它們之間就要加上尺寸為0的Horizontal Space約束。好了,現(xiàn)在有足夠的約束讓自動(dòng)布局系統(tǒng)了解兩個(gè)view之間的關(guān)系了。再給Ray和Dennis Ritchie視圖之間使用Editor/Pin/Vertical Spacing。
再運(yùn)行app,現(xiàn)在看起來就像這樣:

注意:Interface Builder任然會抱怨view的位置不對。我不確信為什么會發(fā)生這種情況,可能是Xcode有bug吧。如果這些警告信息讓你不爽,那就選擇主視圖(或view控制器)并且從Resolve Auto Layout Issues菜單選擇Update All Frames in View Controller。不過你的app運(yùn)行時(shí)這種改變不會起作用,但至少讓Xcode看起來很舒心。
image view上有一點(diǎn)要注意:它們可能會延伸了,因?yàn)槟銢]有給它們一個(gè)固定尺寸。你可能不知道,這是有意這樣做的。image view不能適配橫屏的模式。如果你想保持image view的原始寬高比,那很不幸。在Interface Builder中你是無法得到下面這樣的效果的:

不幸的是,Interface Builder不能正確的提供用約束保持view的原樣寬高比。如果要這么做,你就需要自己編程。你可以在iOS 6 by Tutorials的“Intermediate Auto Layout”中學(xué)習(xí)如何操作。
如果你全都看完做完了,祝賀你 - 你現(xiàn)在知道自動(dòng)布局是什么了,并且有了一定的實(shí)踐基礎(chǔ)!但你任然有許多需要學(xué)習(xí)...
這個(gè)教程的第一部分你可以從iOS 6 by Tutorials一書中的自動(dòng)布局章節(jié)閱讀到。第二部分會教你如何使用自動(dòng)布局來創(chuàng)建更多“真實(shí)世界”的場景布局,你可以從Interface Builder學(xué)習(xí)一切你想知道的自動(dòng)布局的知識。
但是就像其他的視覺設(shè)計(jì)工具一樣,Interface Builder也有自己的局限性。有時(shí),它只能通過NSLayoutConstraint對象來從代碼實(shí)現(xiàn)。IOS 6的教程有一個(gè)章節(jié)包含了這個(gè)主題所有的內(nèi)容,Intermediate Auto Layout。因此,如果你想知道自動(dòng)布局的后半部分,請買這本書吧!(翻譯到最后,發(fā)現(xiàn)居然帶廣告,為了尊重原作者,還是給出連接吧~~~)
新聞熱點(diǎn)
疑難解答
圖片精選