上一篇講了一大堆基礎(chǔ)知識(shí),現(xiàn)在就開(kāi)始講一下AutoLayout的實(shí)際應(yīng)用。接下來(lái)我們要用Xcode做一個(gè)典型的登錄頁(yè)面。這個(gè)頁(yè)面會(huì)用到我在上一篇里講過(guò)的三種布局方式。完成以后是一個(gè)真實(shí)的登錄界面,換句話說(shuō),這是一個(gè)真實(shí)的iOS App,只是這個(gè)App只有一個(gè)不能登錄的登錄界面。
看完這篇文章后你會(huì)大概了解你的設(shè)計(jì)是如何實(shí)現(xiàn)的,并且能自己制作出簡(jiǎn)單的頁(yè)面來(lái)。順便聲明一下,本文的討論范圍僅限于iOS開(kāi)發(fā),并且只討論AutoLayout的布局方式,想了解更多布局的基礎(chǔ)知識(shí)的可以看我上一篇文章,未做特殊說(shuō)明的不帶單位的尺寸默認(rèn)單位都為point。
下面正式開(kāi)始,這個(gè)就是我們要做的登錄界面。

首先你需要有一個(gè)Mac電腦,并且要安裝了Xcode,你可以直接在Mac App Store 里下載,這是免費(fèi)的。Xcode 是蘋果給開(kāi)發(fā)者提供的開(kāi)發(fā)軟件,我們平時(shí)用的iOS App 就是這里開(kāi)發(fā)出來(lái)的,事實(shí)上幾乎所有蘋果設(shè)備上的軟件都是用Xcode開(kāi)發(fā)的,包括Mac ,Apple Watch上的軟件。Xcode是一個(gè)強(qiáng)大的開(kāi)發(fā)工具,有很多功能,我在這里只是大致介紹一下本文需要用到的功能,更多內(nèi)容可以點(diǎn)擊這里:http://help.apple.com/xcode/mac/8.0/
創(chuàng)建你的第一個(gè)Xcode項(xiàng)目
安裝好后打開(kāi)Xcode 創(chuàng)建你的第一個(gè)項(xiàng)目吧。

打開(kāi)后選擇 Create a new Xcode project —> 出現(xiàn)默認(rèn)選中的Single View Application,直接點(diǎn)next —> 給你的App取個(gè)名字,點(diǎn)擊next —> 選擇保存地址 就可以了。這就是打開(kāi)后你看到的界面 :

用過(guò)Sketch的人可能會(huì)比較熟悉上面這個(gè)界面的結(jié)構(gòu)。
首先看左邊欄,這個(gè)可以理解為導(dǎo)航欄,在這里我們可以選擇打開(kāi)不同的文件。本文中我們需要用到的是兩個(gè),一個(gè)是Main.storyboard ,這個(gè)是讓我們來(lái)布局界面的畫布,還有一個(gè)是Assets.xcassets ,這個(gè)是讓我們放素材的地方,我們可以把切圖導(dǎo)入到這里,供后續(xù)使用。

右邊欄大概可以理解為屬性欄,里面的內(nèi)容會(huì)根據(jù)你選中的東西不同而變化,顯示出相應(yīng)的內(nèi)容。
首先我們要導(dǎo)出需要的素材。我導(dǎo)出的是@1x ,@2x,@3x 三種倍率的,如果你的命名符合規(guī)范的話(后綴為@1x ,@2x,@3x),Xcode能自動(dòng)識(shí)別倍率。我們也可以導(dǎo)入一張PDF,Xcode會(huì)自己生成不同倍率的圖(具體做法在這里不說(shuō)了,有興趣的可以自己研究下)。

需要說(shuō)明一下的是我的登錄按鈕切圖并不是一個(gè)長(zhǎng)的按鈕,而只截了一段,因?yàn)檫@個(gè)按鈕長(zhǎng)度會(huì)根據(jù)屏幕寬度調(diào)整,而不是固定的,接下來(lái)我們會(huì)在Xcode里處理一下,讓這個(gè)切圖在寬度方向能自由伸縮,但又不讓圖片失真變形。
導(dǎo)入切圖
先選中Assets.xcassets , 將我們導(dǎo)出的切圖拖到里面。

如果你的命名是符合規(guī)范的,那么Xcode已經(jīng)將你的切圖自動(dòng)識(shí)別到對(duì)應(yīng)的倍率框里面去了

然后我們處理一下之前說(shuō)的那個(gè)登陸按鈕。選擇頂部的菜單中的Editor —> Show Slicing

這時(shí)候你會(huì)發(fā)現(xiàn)你的切圖預(yù)覽變成這樣了:

點(diǎn)擊Start Slicing 接著再點(diǎn)擊 Slice Horizontally 的圖標(biāo)既可以了。想了解細(xì)節(jié)的可以看這里:https://developer.apple.com/library/ios/recipes/xcode_help-image_catalog-1.0/chapters/SlicinganImage.html

Tips:有些由簡(jiǎn)單色塊組成的圖片,如背景,按鈕背景等切圖并不需要切出一張完整的圖片。
開(kāi)始布局
處理完素材以后我們就可以正式開(kāi)始了。在導(dǎo)航欄里選擇Main.storyboard,你會(huì)看到頁(yè)面的中間出現(xiàn)了一個(gè)叫View Controller正方形的畫布。

看一下登錄界面的頁(yè)面構(gòu)成,我用紅字標(biāo)的是我們等下需要用到的控件,我們可以在iOS的控件庫(kù)里面找到這些控件,直接將它們拖到我們的畫布上去。
最上面是一個(gè)Navigation Bar 這是iOS系統(tǒng)的自帶的,并不需要我們自己來(lái)做,我們只需要把Navigation Bar調(diào)出來(lái)就行了。

調(diào)出Navigation bar
首先我們先選中View Controller,選擇頂部菜單欄中的Editor中的Embed in Navigation Controller ,這樣我們的View Controller上就會(huì)出現(xiàn)Navigation Bar 了。


這時(shí)候我們能看到之前的View Controller 上已經(jīng)出現(xiàn)了一個(gè)Navigation bar ,雙擊中間就能直接輸入標(biāo)題,字體大小都是默認(rèn)的,一般都是使用默認(rèn)字號(hào)。
接下來(lái)就要放Navgation Bar 上的兩個(gè)按鈕了,同樣,這兩個(gè)也是使用系統(tǒng)默認(rèn)的按鈕,位置和大小都是默認(rèn)的,我們只需要從系統(tǒng)的控件庫(kù)里拖兩個(gè)按鈕放上去就行了。Xcode右下角區(qū)域的就是iOS的控件庫(kù),我們平時(shí)用的控件都能在這里找到,你也可以在下面的搜索框中直接輸入你想要的控件進(jìn)行快速查找。這里我們需要的是 Bar Button Item ,找到后直接拖出來(lái)放到我們的Navigation Bar 上就行了。
放上去以后同樣是雙擊就可以直接輸入,我們改好按鈕的標(biāo)題,這時(shí)候發(fā)現(xiàn)默認(rèn)的按鈕是藍(lán)色的,我們?cè)O(shè)計(jì)中的按鈕是綠色的。iOS的系統(tǒng)控件都會(huì)給我們提供一部分自定義的空間,我們只需要選中相應(yīng)控件,就會(huì)在右邊欄的Attributes inspector上出現(xiàn)相應(yīng)控件的屬性,可以看到右邊欄中出現(xiàn)了一個(gè) Tint 的屬性,我們可以在這里修改顏色。
Tips:建議大家去看一下這個(gè)控件庫(kù)里面的東西,了解各個(gè)控件的用處和它們的屬性,這會(huì)對(duì)你的設(shè)計(jì)有很大的幫助。

修改背景色
我們可以直接點(diǎn)擊相應(yīng)控件來(lái)選擇,也可以在畫布邊上的層級(jí)里選擇,這里能看到所有的控件,如果我們點(diǎn)擊View Controller中間的空白位置,就能看到有一個(gè)View被選中了,這是系統(tǒng)默認(rèn)加上去的,可以把它理解為背景。選中這個(gè)View 后我們就能在右側(cè)的屬性欄中修改它的背景顏色了。我們需要把它的 Background 改為灰色就行。

給出適配策略
這些都改好以后,接下來(lái)就是用AutoLayout 布局的時(shí)候了,先分析一下我們要做的頁(yè)面的布局:

第一個(gè)是最上面的Logo ,這是一張圖片,我希望它一直保持圖片的原始大小,不隨著屏幕縮放,防止圖片變虛。所以我希望它的大小是固定的,寬度方向?qū)?yīng)上個(gè)例里的B。
第二個(gè)是輸入框和按鈕區(qū)域,我希望他們的寬度能和屏幕一起縮放,所以寬度方向?qū)?yīng)A。
第三個(gè)是三個(gè)第三方登錄的按鈕,我要求他們之間的間隙能隨著屏幕的變化而變化,充分利用屏幕空間,也就是寬度方向?qū)?yīng)C。
定位圖片
首先從控件庫(kù)里面拖出一個(gè)Image View 到畫布上去,在左側(cè)的Attributes inspector 上的Image選框中選擇我們之前導(dǎo)入的logo

接下來(lái)就到了添加約束的時(shí)候了,最常用的是右下角的四個(gè)按鈕,這次會(huì)用到后三個(gè)。

先介紹一下第一種添加約束的方法:Pin。選中Logo,點(diǎn)擊Pin按鈕,會(huì)出現(xiàn)一個(gè)Add New Constraints的Popup(如下圖),這個(gè)就是我們來(lái)添加約束的地方。上部分用來(lái)定義當(dāng)前選中的視圖和附近的視圖的上下左右的距離,點(diǎn)擊三角形下拉框可以看它附近的視圖有哪些,有多個(gè)的話和可以自己選擇,默認(rèn)是離它最近的那個(gè)。點(diǎn)擊紅色的虛線約束線,變實(shí)線后表明添加了相應(yīng)約束。下面可以設(shè)置寬度和高度,你也可以讓它固定長(zhǎng)寬比(Aspetc Ratio),這樣就算單向拉伸時(shí)你的圖片也不會(huì)變形。如果你一起選擇了多個(gè)視圖,你可以讓他們等高或等寬,還可以進(jìn)行對(duì)齊。

當(dāng)約束線是紅色時(shí),就表明我們添加的約束還有問(wèn)題。可以看到,在上圖左上角有一個(gè)紅色的箭頭,這就報(bào)錯(cuò),點(diǎn)擊后能看到具體的報(bào)錯(cuò)信息:
Need constraints for :X position
這條信息提示我們沒(méi)有給出X方向的位置信息。我們要求這個(gè)圖是居中的,所以要添加一個(gè)水平方向的居中的約束就可以了。這時(shí)候就要用到第二種添加約束的方法了:點(diǎn)擊Align按鈕也會(huì)出現(xiàn)一個(gè)Popup,我們?cè)谶@里進(jìn)行各種對(duì)齊操作。勾選Horizontally in Container,點(diǎn)擊Add 1 Constraint后就行了。

添加上這個(gè)約束后能發(fā)現(xiàn)紅色的線不見(jiàn)了,變成了黃線,還出現(xiàn)了一個(gè)黃色的虛線框。這個(gè)虛線框表示這是Xcode 通過(guò)我們給的約束推斷出來(lái)的位置。我們需要Update Frame,讓這個(gè)logo跑到它該待的位置。

點(diǎn)擊Resolve AutoLayout Issues 按鈕,在出現(xiàn)的Popup里選擇第一個(gè)Update Frames。

Update完成后我們看到Logo 已經(jīng)跑到正確的位置去了,這時(shí)候所有的約束線都變成了藍(lán)色。藍(lán)色的約束線就代表Xcode能通過(guò)現(xiàn)在所加的約束可推斷出頁(yè)面的布局。
定位輸入框和登錄按鈕
接下來(lái)就開(kāi)始定位輸入框,同樣先從控件庫(kù)里面拖出一個(gè)TextField來(lái),在placeholder 里輸入提示文字。順便提一句,TextField的屬性里有一個(gè)Keyboard Type 選框,在這里我們可以選擇該輸入框?qū)?yīng)的輸入鍵盤。如果你的用戶名都是手機(jī)號(hào),那么就應(yīng)該在這里選擇數(shù)字鍵盤。
Tips:在iOS系統(tǒng)里,你可以給每個(gè)輸入框都指定相應(yīng)的鍵盤。當(dāng)你在設(shè)計(jì)輸入框時(shí)可以說(shuō)明它使用的是哪種鍵盤,如只能輸入數(shù)字的輸入框彈出的就因該是數(shù)字鍵盤。

接下來(lái)同樣是用Pin按鈕來(lái)添加約束。要求它離上面的Logo 為30 ,輸入框高度為45,寬度隨著屏幕伸縮,屏幕兩邊各留15的邊距(margin)。需要注意的是這里要取消勾選 Constrain to margins 選項(xiàng)。我們?cè)O(shè)置的margin是15,而蘋果默認(rèn)也會(huì)有一個(gè)margin,當(dāng)這個(gè)選項(xiàng)勾上以后,默認(rèn)的margin也會(huì)算在里面,我們的margin是自定義的,不需要使用默認(rèn)的,所以這里要取消勾選。

添加完成后Update一下,就能看到預(yù)期的效果了。我們可以用同樣的方式定位好第二個(gè)密碼輸入框,但是,這里我們要用另一種方式來(lái)添加約束,也是第三種常用的添加約束的方法。這次我們要以第一個(gè)輸入框?yàn)榛A(chǔ)來(lái)定義第二個(gè)輸入框。讓第二個(gè)輸入框和第一個(gè)一樣高,同時(shí)首尾對(duì)齊。這樣做的好處就是如果我們下次要修改,如修改高度,那么我們只要改第一個(gè),第二個(gè)也會(huì)跟著變化,而不需要再一個(gè)個(gè)去改。
具體的操作方法是先選中你要定位的視圖,按住Control鍵后拖動(dòng)到另一個(gè)視圖上后釋放,會(huì)出現(xiàn)一個(gè)菜單,在菜單里可以選擇它們之間的關(guān)系,按住Shift 后可以多選,選好后按Return 確認(rèn)。

我們?cè)趶棾龅牟藛卫镞x擇讓它們首尾對(duì)齊(Leading , Trailing),等高(Equal Heights),還有加上垂直方向上距離,Vertical Spacing 就是將當(dāng)前的垂直方向的距離作為默認(rèn)的數(shù)值,我們可以雙擊這個(gè)約束線來(lái)修改數(shù)值大小,這里我們將大小改為10 。

完成以后我們從控件庫(kù)里拖出一個(gè)Button ,在Attributes inspector里將標(biāo)題改為“忘記密碼”,顏色改為灰色。用上面的方法讓它與輸入框的 Trailling(尾部) 對(duì)齊,同時(shí)離上一個(gè)輸入框距離也為10 ,放好修改密碼的按鈕。
再拖出一個(gè)Button,用來(lái)做登錄按鈕,將Background改為之前導(dǎo)入的按鈕切圖。用我之前說(shuō)過(guò)的方式添加好約束。這里按鈕的高度為45,離密碼輸入框的距離為60。

第三方登錄模塊
這樣我們的登錄界面大致就完成了。下面還有一個(gè)第三方登錄模塊。首先是“使用第三方賬號(hào)登錄”的標(biāo)簽。這是一個(gè)Label,直接從控件庫(kù)里拖出來(lái),然后修改一下內(nèi)容,顏色,調(diào)整字體,接下來(lái)添加兩個(gè)約束就行了。一個(gè)是屏幕內(nèi)水平方向居中,另一個(gè)是距離上面的登錄按鈕40。寬度和高度會(huì)根據(jù)內(nèi)容自己判斷,不需要添加。

在上圖中的第4步中的修改字體,當(dāng)我們點(diǎn)擊Font輸入框中的灰色箭頭后會(huì)出現(xiàn)一個(gè)Popup,里面的第一個(gè)下拉框是Font ,當(dāng)我們點(diǎn)擊展開(kāi)時(shí),就能看到很多選項(xiàng)了,默認(rèn)選擇的是system。

用過(guò)iOS系統(tǒng)的人都知道,在系統(tǒng)設(shè)置里面可以修改字體的大小,有些人會(huì)將字體都調(diào)大,但很多第三方的App的并不支持這一功能。如果你看過(guò) iOS Human Interface Guidelines的話,你可能會(huì)注意到里面有一章講到過(guò) Dynamic Type。iOS 已經(jīng)設(shè)置一部分字體樣式,如果你使用的是這些系統(tǒng)樣式,那么在設(shè)置里調(diào)大字體后,你的App里的字體也能變大。這樣的功能對(duì)于我們來(lái)說(shuō)可能用處不大,但是對(duì)我們父母來(lái)說(shuō)還是很貼心的。
而這里的Text Styles 正是蘋果提供的字體樣式。具體的樣式對(duì)應(yīng)的字號(hào),以及隨著系統(tǒng)設(shè)置的變化,各個(gè)字體怎么變化,都能查到,我在這里截了一個(gè)在默認(rèn)狀態(tài)下的字體大小。詳情點(diǎn)擊這里:https://developer.apple.com/ios/human-interface-guidelines/visual-design/typography/

再講一些關(guān)于標(biāo)簽(Label)的問(wèn)題,一個(gè)是我在“添加Label”這個(gè)圖上用紅色框框起來(lái)的AutoShrink(自動(dòng)縮放)。通常我們都會(huì)遇到這樣的情況:標(biāo)簽的內(nèi)容特別多顯示不下時(shí),多出來(lái)的內(nèi)容都會(huì)被自動(dòng)截掉,用省略號(hào)代替,有時(shí)候省略掉的甚至是比較重要的信息。而這個(gè)AutoShirnk就是來(lái)解決這個(gè)問(wèn)題的,你可以設(shè)置一個(gè)最小字號(hào)或者一個(gè)最小縮放比例。當(dāng)頁(yè)面變化而導(dǎo)致內(nèi)容顯示不下時(shí),你的標(biāo)簽的字號(hào)首先會(huì)自動(dòng)縮小,直到縮小到你規(guī)定的最小值時(shí)才會(huì)將多出的內(nèi)容省略掉。
另一種方式是多行顯示,同樣在“添加Label”這個(gè)圖上用紅色框框起來(lái)的Lines輸入框,默認(rèn)的是1,就代表只顯示一行,你可以在這里設(shè)置顯示的行數(shù),如果你將它改為0,則代表顯示多行。

Tips:在設(shè)計(jì)iOS軟件時(shí)應(yīng)優(yōu)先考慮使用Dynamic Type,在設(shè)計(jì)Label時(shí)(幾乎每個(gè)App 都會(huì)用到),應(yīng)該考慮各種極限情況,并給出相應(yīng)適配策略。如當(dāng)文字顯示不下時(shí)是讓文字縮小還是省略掉多出來(lái)的內(nèi)容。
回來(lái)繼續(xù)說(shuō)下面三個(gè)第三方登錄按鈕。我的要求是他們之間的間隙隨著屏幕的寬度變化而變化。屏幕寬度越小它們之間靠的就越近,反之則分的越開(kāi)。想要達(dá)到這樣的效果,我們可以先將他們編一個(gè)組,讓這個(gè)組的寬度隨著屏幕變化而變化。
首先我們先拖出一個(gè)UIView,這是一個(gè)最基礎(chǔ)的視圖,將它當(dāng)做放按鈕的容器,也就是上面說(shuō)的組。(這里其實(shí)可以用Stack View 作為這個(gè)容器,使用起來(lái)更簡(jiǎn)單,我在下篇會(huì)詳細(xì)介紹Stack View )

按照上圖的要求添加好約束后,我們會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,因?yàn)檫x擇的是Equal Widths ,導(dǎo)致這個(gè)組的寬度是和屏幕是一樣寬的,這顯然不是我們要的效果。雙擊這個(gè)等寬的約束后,我們能看到我在上一篇里講過(guò)的Multiplier了,只需要修改這個(gè)約束的Multipier,將它改為0.6,這樣,這個(gè)組的寬度就一直是屏幕寬度的60%了。

接下來(lái)我們只要將三個(gè)按鈕固定在這個(gè)組里的最左邊,中間,最右邊就行了。這樣就能到達(dá)我們要的效果了。

添加完成后UpdateFrame,就能看到下圖的效果了。最后我們只要將這個(gè)作為容器的View 的背景改為透明就行了。

這樣,我們的登錄界面就完成了,現(xiàn)在這個(gè)頁(yè)面就能根據(jù)我們的要求適配各個(gè)屏幕尺寸了。我們可以選擇不同的模擬器,查看它在不同設(shè)備上的運(yùn)行效果,無(wú)論橫屏和豎屏它都能跟著調(diào)整。需要注意一下的是在橫屏情況下可能會(huì)有一部分界面超出屏幕范圍,本來(lái)所有元素都應(yīng)該放在一個(gè)ScrollView里,這樣超出屏幕的部分就能向上滑動(dòng)了,這里為了方便演示并沒(méi)有加。

下面就是它不同設(shè)備上的運(yùn)行效果。


可以看到,它不僅支持iPhone,還支持iPad,而且橫屏豎屏都行,應(yīng)對(duì)iPad的多任務(wù)顯示也不在話下。很多人覺(jué)得如果要支持iPad 就需要重新開(kāi)發(fā)一個(gè)App。實(shí)際上在本文的開(kāi)頭,你在創(chuàng)建項(xiàng)目的時(shí)候會(huì)讓你選擇支持的設(shè)備,默認(rèn)的是Univerasl(全平臺(tái)),也就是說(shuō)你要是適配的好,一個(gè)安裝包就能同時(shí)支持iPhone 和 iPad,而不需重新開(kāi)發(fā)。
好了,這篇就講到這里,下一篇我會(huì)介紹一下Stack View 以及更多AutoLayout 的相關(guān)知識(shí)和實(shí)際應(yīng)用。
Via: DDC
