之前在DDC后臺(tái)有粉絲留言說希望我們能寫一篇關(guān)于iOS和Android平臺(tái)特性對(duì)比的文章,筆者曾經(jīng)為兩個(gè)平臺(tái)分別做過差異化的設(shè)計(jì),所以今天想借此話題為大家介紹一下iOS和Android兩個(gè)系統(tǒng)在設(shè)計(jì)方面的差異之處,讓大家能更好的理解其中的異同并運(yùn)用在自己的設(shè)計(jì)當(dāng)中。
作為智能手機(jī)的最大的兩個(gè)陣營,iOS和Android系統(tǒng)差異一向都是大家津津樂道的話題,其中內(nèi)容通常是圍繞“機(jī)器性能好不好,打開軟件卡不卡”“攝像頭的像素高不高,拍出來的自己美不美”“外觀是不是有bigger”等話題展開的。
但在一個(gè)設(shè)計(jì)師眼里,這兩個(gè)系統(tǒng)的差異性之多可遠(yuǎn)遠(yuǎn)不止表面上看起來的那么簡單粗暴。但在移動(dòng)端趨勢有如春草那樣蔓延開來的今天,大多數(shù)的公司都選擇把iOS的界面直接運(yùn)用于Android系統(tǒng)。我們自然可以理解這樣做是為了節(jié)省成本和更快的迭代,但抹殺了系統(tǒng)特性的運(yùn)用卻犧牲了許多Android用戶的用戶體驗(yàn)。盡管知乎也有類似回答過兩個(gè)系統(tǒng)交互的不同,今天筆者想更著重介紹一下兩者設(shè)計(jì)語言的異同。
幾乎每個(gè)移動(dòng)端的設(shè)計(jì)師都會(huì)熟知的一個(gè)Mobile設(shè)計(jì)里程碑——就是iOS7的Flat Design。原本栩栩如生的擬物化設(shè)計(jì)被拍扁,去除了冗余、厚重和繁雜的裝飾效果,扁成了“扁平化設(shè)計(jì)”,其核心思想就是讓“信息”本身凸顯出來,在設(shè)計(jì)元素上則強(qiáng)調(diào)了抽象、極簡和符號(hào)化。自此扁平風(fēng)格開始在移動(dòng)端設(shè)計(jì)中廣為盛行。
圖一自從2014年11月3日,Android5.0 Lollipop正式面向用戶推出,Material Design 煥然一新的設(shè)計(jì)驚艷了全場,不僅僅是視覺效果,全新的“數(shù)字紙墨”的空間概念也賦予了界面全新的UI理念。

那么Flat Design與Material Design,兩個(gè)同樣趨于簡約的設(shè)計(jì)理念,他們具體的區(qū)別又在哪呢? 以下將會(huì)就這個(gè)話題具體分析兩者在設(shè)計(jì)思路、動(dòng)效和其他細(xì)節(jié)上的不同。
如果只能用一對(duì)詞來概括Android和iOS系統(tǒng)的不同,我想那應(yīng)該是開放與封閉,也正是這兩個(gè)截然不同的系統(tǒng)特性帶來了設(shè)計(jì)思路的不同。Android的開放帶來了多樣化設(shè)計(jì)的同時(shí)(使用自定義控件幾乎沒有不能實(shí)現(xiàn)的設(shè)計(jì)效果),同時(shí)也帶來了“雜亂無章”之感和眾多因?yàn)椴唤y(tǒng)一而造成的用戶在使用時(shí)無從下手的情況。而iOS的HIG(《Human Interface Guideline》人機(jī)交互規(guī)范)則更多“迫使”設(shè)計(jì)師去更多的使用系統(tǒng)原生的控件,設(shè)計(jì)師對(duì)于控件的修改非常局限,但這樣做的好處就是每個(gè)App的基本操作都是在規(guī)范之內(nèi),具有一定的統(tǒng)一性,用戶使用起來非常的方便,學(xué)習(xí)成本也相應(yīng)降低了不少。這兩者很難去評(píng)判孰優(yōu)孰劣,可以說“iOS的下限比Android高,但Android的上限比iOS高”,伴隨著大屏?xí)r代的腳步,可以看到雙方都在努力靠近彼此的一個(gè)趨勢,相信在不久的將來,就可以達(dá)到一種“和而不同”的平衡。
現(xiàn)在動(dòng)效的運(yùn)用已經(jīng)成為了許多app的標(biāo)配,合理的動(dòng)效不僅僅是為了視覺效果上的“酷炫”,更是幫助用戶更好的理解層級(jí)、轉(zhuǎn)場關(guān)系和關(guān)注到重點(diǎn)信息的利器。然而細(xì)心的設(shè)計(jì)師會(huì)發(fā)現(xiàn),Android和iOS的動(dòng)效思路是截然不同的。用一句話概括兩邊設(shè)計(jì)語言的物理模型就是:Material Design運(yùn)用的是機(jī)械物理和電磁物理,而iOS的動(dòng)效更多建立在鏡頭運(yùn)動(dòng)和景深變化上。究其設(shè)計(jì)語言的本質(zhì)就是讓用戶可以把客觀經(jīng)驗(yàn)移植到界面的一種思路。
Material Design的隱喻是紙張,用戶的手指就像磁鐵一樣把電子紙墨吸引過來,點(diǎn)擊后就會(huì)泛起“漣漪”作為一個(gè)交互響應(yīng)。而其他物體的排列則按照一種“深淺”的層級(jí)來排布,離手指越近的元素越亮,陰影越深,而離開遠(yuǎn)的元素則越暗,直至淹沒在黑暗之中。


細(xì)觀iOS的系統(tǒng)動(dòng)效可以發(fā)現(xiàn),iOS的桌面就好像一片星空,每個(gè)App都是其中的一個(gè)小星星(點(diǎn)),每當(dāng)用戶去點(diǎn)擊,鏡頭就會(huì)切近,而背景則是隱入了一片高斯模糊的景深之中,這應(yīng)該是每個(gè)iOS用戶最深刻的動(dòng)效體驗(yàn)之一了。高斯模糊也成為了iOS特有的一個(gè)表達(dá)層級(jí)關(guān)系的利器(其中不僅是模糊,還存在著鏡頭晃動(dòng)時(shí)的位移)。同樣類型的動(dòng)效還體現(xiàn)在打開app的時(shí)候由一個(gè)點(diǎn)放大成一個(gè)面,包括“日歷”App和“相冊”App(皆為系統(tǒng)應(yīng)用)中年-日-月切換的操作,均是鏡頭思路的表現(xiàn)形式。


無論是哪種動(dòng)效,本質(zhì)上都是幫助用戶更好的理解界面切換和時(shí)間線之間的關(guān)系,設(shè)計(jì)師們也可以在這兩種系統(tǒng)動(dòng)效的基礎(chǔ)上,設(shè)計(jì)出適合自己產(chǎn)品的動(dòng)效。
對(duì)于需要同時(shí)涉及移動(dòng)端多個(gè)平臺(tái)的設(shè)計(jì)師來說,分辨率是永遠(yuǎn)無法避開的一個(gè)痛點(diǎn)。在iPhone6/iPhone6Plus 問世之前,iOS更受設(shè)計(jì)師歡迎,也更多被作為模板來設(shè)計(jì)的原因,很大一部分是因?yàn)閕OS的分辨率相對(duì)固定,設(shè)計(jì)效果更容易被還原。而Android也一直因?yàn)槠聊怀叽绲亩鄻踊辉O(shè)計(jì)師們所”嫌棄“。所以在設(shè)計(jì)的過程中,不僅僅需要調(diào)整當(dāng)前頁面的最佳設(shè)計(jì)效果,同時(shí)也應(yīng)該思考這樣的設(shè)計(jì)是否符合不同分辨率尺寸下的屏幕顯示效果。之前公眾號(hào)中小雪的《一稿適配iOS7》(鏈接)應(yīng)該會(huì)給大家不少適配方面的啟示。對(duì)于Android來說,無他,唯調(diào)整爾。盡量把設(shè)計(jì)元素的所占空間用百分比來表示,同時(shí)根據(jù)開發(fā)實(shí)現(xiàn)的效果來調(diào)整一些極端情況下具體的間距,以求“滿足大部分主流屏幕的完美顯示以及其他屏幕的可接受顯示”原則。
下圖給大家展示一下iOS與Android的分辨率的轉(zhuǎn)換關(guān)系,在切圖的時(shí)候滿足一定的倍數(shù)關(guān)系,就可以一鍵導(dǎo)出可以同時(shí)適配兩者的切圖了。
1dp(Android)=1pt(iOS)
以48dp@160dpi計(jì)算的話
mdpi 48px (160dpi, 1x) 基礎(chǔ)尺寸,已經(jīng)非常少使用
hdpi 72px (240dpi, 1.5x)低分辨率
xhdpi 96px (320dpi, 2x) 同iOS @2x
xxdpi 144px (480dpi, 3x) 同iOS @3x
xxxdpi 192px (640dpi, 4x) 更大更高更強(qiáng)的分辨率
其實(shí)iOS和Android的設(shè)計(jì)還有許許多多的不同之處,比如字體、Tab bar設(shè)計(jì)、物理鍵操作方式、編輯模式、App體現(xiàn)個(gè)性的方式等等,在此不一一展開了。希望在設(shè)計(jì)移動(dòng)端產(chǎn)品的過程中,設(shè)計(jì)師們可以更多的去思考兩者的異同,并且更多的關(guān)注一下Android系統(tǒng)獨(dú)有特性的運(yùn)用,不僅僅節(jié)省了開發(fā)成本,同時(shí)也更好的為Android用戶所接受。
原文地址:DDC
作者:Doris
]]>
按照計(jì)劃,這篇文章將是這個(gè)系列里的最后一篇了。
在上一篇文章中,為了讓最后的三個(gè)第三方登錄按鈕的間距能夠根據(jù)屏幕的寬度自動(dòng)調(diào)整,我先添加了一個(gè)組,再在組里面添加約束,弄的很復(fù)雜,而且這種方法也有一定的局限性。

我在上篇文章了就講過,這個(gè)問題有更簡單的解決方案。這個(gè)東西叫做StackView,在我之前講過的添加約束的方式中,第一個(gè)按鈕就是。

它可以讓你不用添加約束就能使用Autolayout里的很多功能,以后維護(hù)起來也會(huì)更方便。和上篇文章講的一樣,先拖出三個(gè)按鈕放好,這次不用給他們先放到一個(gè)組里,只要三個(gè)一起選中后,點(diǎn)擊上面說過的Stack按鈕,就將他們放進(jìn)了一個(gè)StackView里了,你可以理解為對(duì)它們進(jìn)行了編組。

編組后發(fā)現(xiàn)三個(gè)按鈕變成垂直排列的同學(xué)先不要急,后面我會(huì)講到如何把它們變成水平分布的。這樣我們就將它們都放到了一個(gè)組里了,接下來先給這個(gè)組添加約束,和之前用的方法一樣。組的寬度還是設(shè)置為屏幕寬度的0.6倍。添加完成后變成這樣了。

但是里面的按鈕并沒有和我們想象的一樣平均分布,在上篇文章中,我們添加了很多約束,將這些按鈕固定在了組里的某些特定的位置。你也可以在StackView里面添加約束,但是這里我們完全沒必要這么做。我們只要選中整個(gè)StackView,就能在右邊欄看到它的屬性了。只要修改一個(gè)選項(xiàng)就能達(dá)到我們要求的效果。

下面我就解釋一下這些選項(xiàng)代表的是什么意思。
第一個(gè): Aixs 定義的是這個(gè)組的分布方向,我們?nèi)齻€(gè)按鈕是水平分布的,所以這里不需要修改,如果你編組后他們是垂直分布的,只需要在這里將它們改成Horizontal就行了。
第二個(gè) :Alignment 定義的是組內(nèi)元素的對(duì)齊方式,你可以在這里設(shè)置上對(duì)齊,下對(duì)齊之類的,因?yàn)檫@三個(gè)按鈕大小是一樣的,所以對(duì)齊方式也無所謂了,使用默認(rèn)的就行。
第三個(gè):Distribution 定義的是他們的分布方式,我們只要在這里選擇equal spaceing 就能讓他們平均分布了。
第四個(gè) : Spaceing 是用來定義相鄰元素之間的距離的,你可以在后面的輸入框中輸入你想要的數(shù)值。
修改好了Distribution后,我們的工作就完成了。

StackView的威力不限于此,假設(shè)現(xiàn)在產(chǎn)品經(jīng)理屁顛屁顛地跑來和你說,我們又多了一個(gè)第三方登錄的渠道,需要加上去。如果你使用的是我在上篇文章中的做法,那么現(xiàn)在你必須從頭來過,而且那種將三個(gè)按鈕放在最左,中間,最右的做法也完全失效了,必須得想出新的辦法來。
而如果你使用的是StackView,那這個(gè)問題完全不叫什么問題,你只要從控件庫里面拖出一個(gè)新的按鈕,直接扔到這個(gè)StackView里面就行了,其他的東西都是自動(dòng)幫你搞定的。

再講一個(gè)StackView的實(shí)際應(yīng)用,假設(shè)我們設(shè)計(jì)了這樣一個(gè)頁面,想象一下,如果你一個(gè)個(gè)的去添加約束的話,會(huì)是一件多么麻煩的事情,而當(dāng)需要在中間在插進(jìn)一行新的內(nèi)容的時(shí)候,那會(huì)讓你更加痛苦。

而如果你使用的是StackView的話,這一切都變的非常簡單。首先你將左邊的一整列都放進(jìn)一個(gè)StackView里面,這時(shí)候的Aixs應(yīng)該是Vertical,在Alignment里將對(duì)齊方式改為Trailing(尾對(duì)齊),然后Spaceing里面調(diào)整一下行間距就可以了。
用同樣的方式將右邊的文字也都放進(jìn)一個(gè)StackView里面,Alignment里設(shè)置Leading(首對(duì)齊),將Spaceing里的數(shù)字調(diào)整到和左邊的一樣。
最后將左右兩個(gè)StackView再放進(jìn)一個(gè)StackView里面,根據(jù)需要在Spaceing 里面調(diào)整它們之間的距離。將這個(gè)總的StackView放到你想要的位置就完成了。要添加新的一行,只需要將它們拖進(jìn)之前設(shè)置好的StackView里就可以了。
StackView背后使用的也是AutoLayout,所以你還可以在StackView里面添加約束,做出更復(fù)雜的頁面布局。
事實(shí)上蘋果建議你將StackView作為一個(gè)最基礎(chǔ)的元素來構(gòu)建你的整個(gè)頁面,因?yàn)樗鼘?shí)在是太方便了。
我在之前講過,只有當(dāng)能從你給的約束關(guān)系中推斷出位置和大小信息,而且還沒有沖突時(shí),才能通過。
在現(xiàn)實(shí)開發(fā)中,有可能會(huì)出現(xiàn)約束之間沖突的情況,這時(shí)候我們該如何處理呢?實(shí)際上不是所有的約束都是必須滿足的。還記得我在上篇文章中講過的雙擊修改約束嗎?雙擊約束線后會(huì)彈出這樣一個(gè)Popup,其中第二行的Priority 就是這個(gè)約束的優(yōu)先級(jí)。

你可以給約束設(shè)定一個(gè)優(yōu)先級(jí),從0到1000,默認(rèn)約束的優(yōu)先級(jí)為1000,也就是說是必須滿足的。但如果你將優(yōu)先級(jí)調(diào)整到0到999之間,那就意味著這個(gè)約束并不是必須滿足的,而是根據(jù)實(shí)際情況來取舍。當(dāng)出現(xiàn)沖突時(shí),AutoLayout會(huì)根據(jù)Priority數(shù)值的大小來選擇優(yōu)先滿足哪些約束,數(shù)值越高,就越優(yōu)先滿足。
可是我們不該在一開始就避免去設(shè)置有沖突的約束么?如果我們一開始就去避免這個(gè)問題,那優(yōu)先級(jí)還有什么用?
下面我講一個(gè)例子來演示一下約束優(yōu)先級(jí)的實(shí)際應(yīng)用。
假設(shè)我們在做一個(gè)軟件,在這個(gè)軟件里我們給出了兩種基本的操作:打賞 和 支持。
規(guī)則是這樣的:打賞就是你給這個(gè)作者一定的虛擬幣,每個(gè)用戶可以進(jìn)行無限次數(shù)的打賞。
支持,則更多的是精神上的自持,每個(gè)用戶對(duì)于某個(gè)特定的觀點(diǎn)只能支持一次。
通過以上的描述我們可以設(shè)計(jì)這樣兩個(gè)按鈕:

因?yàn)橹С职粹o只有一次點(diǎn)擊機(jī)會(huì),所以當(dāng)支持按鈕點(diǎn)擊過后它就變成不可點(diǎn)擊狀態(tài),它的使命也就完成了。

但是,既然“支持”這個(gè)按鈕點(diǎn)過以后就失效了,為什么不將它拿掉不顯示呢??墒侨绻サ糁С职粹o,那么和支持按鈕相關(guān)的約束都沒有了,打賞按鈕的寬度是沒有被定義的。該如何來解決這個(gè)問題呢?
答案就是再創(chuàng)建一個(gè)約束,將打賞的尾部和屏幕最右邊的距離設(shè)置為10 。這樣打賞按鈕的尾部有了兩個(gè)約束了,一個(gè)說我要和支持按鈕保持10的距離,一個(gè)說我要和屏幕的右邊保持10的距離,顯然這兩個(gè)約束是沖突的。解決這個(gè)沖突的辦法就是將新加的約束的優(yōu)先級(jí)降低。在下圖我用虛線表示。

這樣初始狀態(tài)時(shí),因?yàn)榈诙€(gè)約束并不是必須滿足的,所以一開始是被舍棄的。但是當(dāng)支持按鈕被移除后,這個(gè)新加的按鈕正好能派上用處。這樣頁面就變成了這樣:

前面我講的約束都是一個(gè)固定的數(shù)值,但實(shí)際上著并不是必須要這樣的。你可以設(shè)置他們之間的關(guān)系,大于等于某個(gè)值,等于某個(gè)值,小于等于某個(gè)值。再看一下修改約束的Popup,第一個(gè)選項(xiàng)就是讓你選擇這個(gè)關(guān)系,只不過默認(rèn)的是等于。

下面再看一個(gè)實(shí)際情況。

假如我有這樣一行內(nèi)容,前面是描述,后面是內(nèi)容,我們規(guī)定了它們各自離開屏幕兩個(gè)邊的距離。但是我們并不是十分關(guān)心它們之間的距離,所以我們可以不設(shè)置它們之間的約束,讓他們根據(jù)顯示的內(nèi)容自動(dòng)調(diào)整好了。然而,當(dāng)后面這個(gè)交易編號(hào)變的特別長的時(shí)候,就會(huì)出現(xiàn)文字疊加的情況。所以為了保證它們不重疊,我們還是需要在他們之間設(shè)置一個(gè)約束,如規(guī)定它們的距離必須大于等于10。這樣大多數(shù)情況下能保證這兩個(gè)label還是能自由伸縮,而且不會(huì)出現(xiàn)重疊的情況。當(dāng)編號(hào)變的特別長時(shí)可以觸發(fā)新的適配機(jī)制,如讓編號(hào)的字體縮小,而不是直接重疊到前面的標(biāo)題上去。

不得不承認(rèn)的是,有時(shí)候設(shè)置約束是一件很麻煩的事情,特別是你面對(duì)的是復(fù)雜的界面的時(shí)候,而有時(shí)候,你還沒想好要設(shè)置成怎么樣,只是想先試試。這時(shí)候你就可以試試蘋果推出的新功能,前提是你要把你的Xcode 升級(jí)到8.0以上。
這個(gè)功能就是Auotresizing,它讓你不設(shè)置約束就能快速驗(yàn)證你的想法。它使用起來也非常簡單,在選中你要設(shè)置的視圖的前提下,當(dāng)你選擇左邊欄中的標(biāo)尺icon 后就能看到Auotresizing功能了。

能看到中間的正方形四周有四個(gè)約束,虛線狀態(tài)下表示這個(gè)約束沒有添加,當(dāng)你點(diǎn)一下后,它就會(huì)變成實(shí)線,表示已經(jīng)添加上了,而中間的兩個(gè)帶有箭頭的虛線則代表是否允許伸縮。默認(rèn)是不允許的,如果你點(diǎn)擊寬度方向的以后,這條線就變成了實(shí)線,表示寬度方向是可以自由伸縮的。邊上還會(huì)有一個(gè)小動(dòng)畫來告訴你這些視圖會(huì)怎么變。有興趣的可以去嘗試一下。
到這里,這個(gè)系列的文章就算結(jié)束了。當(dāng)然我這個(gè)系列的文章里不可能提到所有和AutoLayout的知識(shí)。很多人看完以后可能也就忘了如何去添加約束,但是我覺我寫這個(gè)系列的文章,最大的目的不是讓你看完以后能像程序員一樣去開發(fā)自己設(shè)計(jì)的頁面了,而是讓你了解這種相對(duì)布局的思想。希望看完這一系列文章后,當(dāng)你再次看設(shè)計(jì)稿時(shí),能有一種新的視角。
Via: DDC
]]>
上一篇講了一大堆基礎(chǔ)知識(shí),現(xiàn)在就開始講一下AutoLayout的實(shí)際應(yīng)用。接下來我們要用Xcode做一個(gè)典型的登錄頁面。這個(gè)頁面會(huì)用到我在上一篇里講過的三種布局方式。完成以后是一個(gè)真實(shí)的登錄界面,換句話說,這是一個(gè)真實(shí)的iOS App,只是這個(gè)App只有一個(gè)不能登錄的登錄界面。
看完這篇文章后你會(huì)大概了解你的設(shè)計(jì)是如何實(shí)現(xiàn)的,并且能自己制作出簡單的頁面來。順便聲明一下,本文的討論范圍僅限于iOS開發(fā),并且只討論AutoLayout的布局方式,想了解更多布局的基礎(chǔ)知識(shí)的可以看我上一篇文章,未做特殊說明的不帶單位的尺寸默認(rèn)單位都為point。
下面正式開始,這個(gè)就是我們要做的登錄界面。

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

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

用過Sketch的人可能會(huì)比較熟悉上面這個(gè)界面的結(jié)構(gòu)。
首先看左邊欄,這個(gè)可以理解為導(dǎo)航欄,在這里我們可以選擇打開不同的文件。本文中我們需要用到的是兩個(gè),一個(gè)是Main.storyboard ,這個(gè)是讓我們來布局界面的畫布,還有一個(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ì)自己生成不同倍率的圖(具體做法在這里不說了,有興趣的可以自己研究下)。

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

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

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

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

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

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

這些都改好以后,接下來就是用AutoLayout 布局的時(shí)候了,先分析一下我們要做的頁面的布局:

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

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

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

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

添加上這個(gè)約束后能發(fā)現(xiàn)紅色的線不見了,變成了黃線,還出現(xiàn)了一個(gè)黃色的虛線框。這個(gè)虛線框表示這是Xcode 通過我們給的約束推斷出來的位置。我們需要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能通過現(xiàn)在所加的約束可推斷出頁面的布局。
接下來就開始定位輸入框,同樣先從控件庫里面拖出一個(gè)TextField來,在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í)可以說明它使用的是哪種鍵盤,如只能輸入數(shù)字的輸入框彈出的就因該是數(shù)字鍵盤。

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

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

我們在彈出的菜單里選擇讓它們首尾對(duì)齊(Leading , Trailing),等高(Equal Heights),還有加上垂直方向上距離,Vertical Spacing 就是將當(dāng)前的垂直方向的距離作為默認(rèn)的數(shù)值,我們可以雙擊這個(gè)約束線來修改數(shù)值大小,這里我們將大小改為10 。

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

這樣我們的登錄界面大致就完成了。下面還有一個(gè)第三方登錄模塊。首先是“使用第三方賬號(hào)登錄”的標(biāo)簽。這是一個(gè)Label,直接從控件庫里拖出來,然后修改一下內(nèi)容,顏色,調(diào)整字體,接下來添加兩個(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)擊展開時(shí),就能看到很多選項(xiàng)了,默認(rèn)選擇的是system。

用過iOS系統(tǒng)的人都知道,在系統(tǒng)設(shè)置里面可以修改字體的大小,有些人會(huì)將字體都調(diào)大,但很多第三方的App的并不支持這一功能。如果你看過 iOS Human Interface Guidelines的話,你可能會(huì)注意到里面有一章講到過 Dynamic Type。iOS 已經(jīng)設(shè)置一部分字體樣式,如果你使用的是這些系統(tǒng)樣式,那么在設(shè)置里調(diào)大字體后,你的App里的字體也能變大。這樣的功能對(duì)于我們來說可能用處不大,但是對(duì)我們父母來說還是很貼心的。
而這里的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)的問題,一個(gè)是我在“添加Label”這個(gè)圖上用紅色框框起來的AutoShrink(自動(dòng)縮放)。通常我們都會(huì)遇到這樣的情況:標(biāo)簽的內(nèi)容特別多顯示不下時(shí),多出來的內(nèi)容都會(huì)被自動(dòng)截掉,用省略號(hào)代替,有時(shí)候省略掉的甚至是比較重要的信息。而這個(gè)AutoShirnk就是來解決這個(gè)問題的,你可以設(shè)置一個(gè)最小字號(hào)或者一個(gè)最小縮放比例。當(dāng)頁面變化而導(dǎo)致內(nèi)容顯示不下時(shí),你的標(biāo)簽的字號(hào)首先會(huì)自動(dòng)縮小,直到縮小到你規(guī)定的最小值時(shí)才會(huì)將多出的內(nèi)容省略掉。
另一種方式是多行顯示,同樣在“添加Label”這個(gè)圖上用紅色框框起來的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í)是讓文字縮小還是省略掉多出來的內(nèi)容。
回來繼續(xù)說下面三個(gè)第三方登錄按鈕。我的要求是他們之間的間隙隨著屏幕的寬度變化而變化。屏幕寬度越小它們之間靠的就越近,反之則分的越開。想要達(dá)到這樣的效果,我們可以先將他們編一個(gè)組,讓這個(gè)組的寬度隨著屏幕變化而變化。
首先我們先拖出一個(gè)UIView,這是一個(gè)最基礎(chǔ)的視圖,將它當(dāng)做放按鈕的容器,也就是上面說的組。(這里其實(shí)可以用Stack View 作為這個(gè)容器,使用起來更簡單,我在下篇會(huì)詳細(xì)介紹Stack View )

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

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

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

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

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


可以看到,它不僅支持iPhone,還支持iPad,而且橫屏豎屏都行,應(yīng)對(duì)iPad的多任務(wù)顯示也不在話下。很多人覺得如果要支持iPad 就需要重新開發(fā)一個(gè)App。實(shí)際上在本文的開頭,你在創(chuàng)建項(xiàng)目的時(shí)候會(huì)讓你選擇支持的設(shè)備,默認(rèn)的是Univerasl(全平臺(tái)),也就是說你要是適配的好,一個(gè)安裝包就能同時(shí)支持iPhone 和 iPad,而不需重新開發(fā)。
好了,這篇就講到這里,下一篇我會(huì)介紹一下Stack View 以及更多AutoLayout 的相關(guān)知識(shí)和實(shí)際應(yīng)用。
Via: DDC
單位:
pt:ios開發(fā)單位,即point,絕對(duì)長度,1pt=1/72英寸。
ppi:Pixels Per Inch,即每英寸所擁有的像素?cái)?shù)目,屏幕像素密度。
公式:
舉例:
比如iphone3gs的像素分辨率是480px×320px,按下圖計(jì)算即表示在iphone3gs具有ppi為163,物理屏幕寬度約為3英寸,3*163~480,
因此iphone3gs分辨率為480*320

由于iphone3GS和iphone4的物理屏幕尺寸的大小是一樣的,所以,他們的pt是相同的。但是由于iphone4的現(xiàn)實(shí)像素為960px×640px,也就是說每英寸在iphone4的屏幕下顯示了326個(gè)像素(剛好是iphone3GS的2倍)。

即在同一物理長度pt長度下,iphone4的屏幕像素密度是iPhone3GS的2倍,因此像素分辨率是iphone3gs的2倍。
這也就是為什么當(dāng)我們在做iOS客戶端的設(shè)計(jì)時(shí)候(通常我們以@2x來設(shè)計(jì)),開發(fā)說的圖片尺寸多少pt,換算成要乘以2的原因了(如果我們做iphone6+的設(shè)計(jì)要在pt數(shù)×3)的由來了。
再去看iphone的各個(gè)尺寸就很簡單了??梢钥闯鰅phone的屏幕密度只有3種,即
@1x,163ppi(iphone3gs)
@2x,326ppi(iphone4、4s、5、5s、6)
@3x,401ppi(iphone6+)

原文鏈接:jianshu
智能手機(jī)發(fā)展到今天,屏幕尺寸變的越來越多,iPhone從最初的3.5寸屏幕,到后來推出的4寸屏,直到蘋果推出iPhone 6 和 iPhone 6Plus,也宣告著蘋果陣營被徹底攻破,進(jìn)入了屏幕尺寸碎片化的時(shí)代。只為某一個(gè)屏幕尺寸設(shè)計(jì)的日子已經(jīng)不在存在。為了適配所有的屏幕,設(shè)計(jì)師必須考慮各種屏幕尺寸。但是又不可能為每個(gè)尺寸都設(shè)計(jì)一遍。那么我們又該如何面對(duì)屏幕碎片化的困境?

蘋果給出的答案是AutoLayout。讓你能用一個(gè)設(shè)計(jì)來適配所有屏幕,理論上講從iPhone4適配到iPad pro都可以。它希望你忘記某個(gè)具體的尺寸。實(shí)際上你可以隨意拖出一個(gè)任意尺寸的畫布進(jìn)行設(shè)計(jì),標(biāo)注好后就可以交給工程師開發(fā)。
首先我們先看一下,蘋果的開發(fā)軟件Xcode上是讓你怎么進(jìn)行頁面布局的。

中間那塊白色的正方形就是畫布,如果你是使用storyboard布局的話(iOS的布局方式有很多種,storyboard只是其中一種,我在后面會(huì)講),你可以將你設(shè)計(jì)好的控件放到這個(gè)畫布上去,根據(jù)你標(biāo)注的尺寸定義好它們的位置關(guān)系,接下來AutoLayout就會(huì)自動(dòng)適配各個(gè)屏幕了。聽上去好像很神奇。
有些人會(huì)有疑問:我是以iPhone6的尺寸為基礎(chǔ)進(jìn)行設(shè)計(jì)和標(biāo)注的,怎么可能在一個(gè)正方形上根據(jù)我標(biāo)注的尺寸定好它們的位置關(guān)系,放到這個(gè)正方形上,我的標(biāo)注不是全亂了嗎?答案是,是,也是不是。如果你在設(shè)計(jì)和標(biāo)注時(shí)只為iPhone6設(shè)計(jì),把適配的問題都拋給了工程師,很有可能最后出來的結(jié)果不是你想要的。相反,即使你是在iPhone6上進(jìn)行設(shè)計(jì),但是你并沒有把思維局限在某個(gè)尺寸上,那么你的標(biāo)注放在正方形上也不會(huì)亂。
確切的講,如果你是以約束為基礎(chǔ)(constraint-based)來設(shè)計(jì)的界面,那么無論屏幕怎么變化,你的設(shè)計(jì)也會(huì)跟著進(jìn)行調(diào)整。
下面我就來講講AutoLayout到底是如何工作的,以及該如何用約束的思想來進(jìn)行設(shè)計(jì)。
對(duì)于iOS開發(fā)來講,通常會(huì)使用的是兩種布局方式。一種是使用代碼設(shè)置每個(gè)視圖(View)的Frame來進(jìn)行定位。另一個(gè)則是使用AutoLayout進(jìn)行布局(可以在storyboard上,也可以使用代碼)。假設(shè)我們在iPhone6(375*667)的尺寸下放了有兩個(gè)視圖,A和B。
Tips:在iOS開發(fā)中使用的單位是point,也就是@1x下的尺寸。如果你是以iPhone6(750*1334Px)的尺寸進(jìn)行設(shè)計(jì)的,那么里面的尺寸都要除以2才能用。所以建議大家在@1x的環(huán)境下設(shè)計(jì)。本文不做特殊說明,沒標(biāo)單位的標(biāo)注,默認(rèn)單位都為point。
設(shè)置Frame進(jìn)行定位的方法不是本文討論的重點(diǎn),我只在這里簡單介紹一下。首先在iOS里的坐標(biāo)系和我們平時(shí)用的有點(diǎn)不同。它的坐標(biāo)原點(diǎn)在左上角。每個(gè)視圖都有自己獨(dú)立的坐標(biāo)系。見下圖。

通常我們定義一個(gè)Frame的代碼(Swift)是這樣的:
let frame = CGRectMake(x:CGFloat, y:CGFloat, width:CGFloat, height:CGFloat)
當(dāng)然你不需要看懂它,只需要知道它要你提供四個(gè)參數(shù):x,y,width,height。x ,y 是你要定位的視圖的原點(diǎn)相對(duì)于包含它的視圖的(superView)坐標(biāo)系的坐標(biāo)。width,height 當(dāng)然就是你要定位的視圖的寬度和高度了。
總結(jié)一下就是你需要提供位置信息(location)以及尺寸(size)信息。
所以上圖中A,和 B的Frame應(yīng)該是這樣的:
let frameA = CGRectMake(60, 60, 255, 160)
let frameB = CGRectMake(60, 280, 255, 160)
AutoLayout布局背后的邏輯則完全不同于上一種方式。同一個(gè)圖,AutoLayout可以用下圖這種方式來表示。

AutoLayout是通常是通過定義一系列的約束(constrains)來進(jìn)行定位的。和Frame定位一樣,它同樣需要你提供位置和尺寸信息,但是和Frame不同的是,它不是讓你直接提供x,y,width,height,而是通過你給的約束來推斷出相應(yīng)的尺寸和位置。只有當(dāng)能從你給的約束關(guān)系中推斷出位置和大小信息,而且還沒有沖突時(shí),才能通過。
如上圖中的視圖A,我們通過上下左右四個(gè)約束定好了它的位置。我們提供了它的高度,但是我們并沒有給出它的寬度。之前說過,要確定一個(gè)視圖的布局,你需要提供位置以及尺寸信息。而這里我們卻沒有提供寬度。應(yīng)為寬度不是一個(gè)固定的數(shù)值,需要AutoLayout自己通過現(xiàn)有的約束來推斷出視圖A的寬度 = 375(屏幕寬度)— 60—60 = 255,這樣當(dāng)屏幕寬度變化時(shí),視圖A的寬度也會(huì)隨之變化。
AutoLayout能夠根據(jù)你在相應(yīng)視圖上設(shè)置的約束,自動(dòng)計(jì)算出的你定義的視圖的位置和大小。

當(dāng)周邊環(huán)境變化時(shí),它也隨之改變,這就是AutoLayout能適配不同屏幕的秘訣。
AutoLayout的應(yīng)用并不局限于應(yīng)對(duì)外部環(huán)境的變化(屏幕大小變化),即使在同一個(gè)屏幕內(nèi),當(dāng)頁面內(nèi)容開始變化時(shí),AutoLayout也能做出相應(yīng)的調(diào)整。假設(shè)現(xiàn)在因?yàn)槟撤N原因,視圖A的高度變?yōu)榱?10。那么就會(huì)出現(xiàn)以下兩種結(jié)果:

用Frame定位方式,因?yàn)橐晥DA,B的位置信息是獨(dú)立的,A的變化,并不會(huì)影響B(tài)的位置,所以當(dāng)A變高時(shí),A,B之間高度方向的距離就被壓縮了,可以想象,當(dāng)A繼續(xù)變高時(shí),A和B之間就會(huì)出現(xiàn)疊加的情況,這顯然不是我們希望看到的效果。
而AutoLayout則不同,由于B高度方向的位置是相對(duì)于A的,所以當(dāng)A變高時(shí),B的位置也會(huì)跟著變化。這當(dāng)然是我們希望看到的結(jié)果。
由此可見,AutoLayout的應(yīng)用場景不局限于適配不同的屏幕尺寸,即使在軟件運(yùn)行的過程中,當(dāng)頁面變化時(shí)它也能夠跟著調(diào)整。
需要提一下的是,使用Frame定位的方式也是能實(shí)現(xiàn)上面這種AutoLayout的效果的,反之我們也能使用AutoLayout來實(shí)現(xiàn)像Frame這種A,B不相互影響效果,我在這里不細(xì)說,有興趣的可以自己去思考一下。舉這個(gè)例子,只是為了說明絕對(duì)定位和相對(duì)定位的區(qū)別。
相對(duì)于Frame通常要你提供的x,y,width,height,AutoLayout可用的屬性則多的多,常用的屬性有這些:
Left
Right
Top
Bottom
Leading
Trailing
Width
Height
CenterX
CenterY
Baseline
查看所有屬性可點(diǎn)擊這里:

這些屬性也大概可以分為兩類:大小(size)如width ,height ;位置(Location)如Leading,Trailing,Top,Button。
有了這些屬性,我們不僅能夠定義不同視圖之間的距離,讓它們對(duì)齊,定義不同視圖之間的相對(duì)尺寸,甚至可以定義一個(gè)視圖的長寬比。
值得注意的是其中的Leading 和Trailing,并不等于Left和Right。Leading代表的是閱讀開始位置。通常我們都是習(xí)慣從左邊到右來閱讀,這種情況下Leading就是Left,Trailing就是Right。但并不是所有的國家都是依照這個(gè)方式的,比如中國古代的書,就是從右到左的,這時(shí)候Leading就在Right了。如果你的App用戶是國際化的,需要注意這個(gè)問題。通常情況下,我們都使用Leading,Trailiing。


假設(shè)我們有以上兩個(gè)View,現(xiàn)在要求他們間隔距離為8,如上圖所示。那么他們之間的約束關(guān)系就可以這么表示:
ViewB.Leading = 1.0 x ViewA.Trailing + 8
其中1.0 是一個(gè)系數(shù)(Multiplier),這種情況下,這個(gè)系數(shù)為1.0
下面就講一個(gè)具體的例子來說明一下AutoLayout應(yīng)用。
假設(shè)我設(shè)計(jì)了一個(gè)這樣的界面(375*667),接下來要交給工程師進(jìn)行開發(fā)。我的要求如下:
1.三個(gè)視圖離頁面兩邊的距離都為37.5
2.每個(gè)視圖之間的距離,包括視圖離頁面頂端和底端的距離都要一樣,為40
3.三個(gè)視圖的寬度和高度要一樣。
我按照這些要求進(jìn)行了標(biāo)注,以下就是我想達(dá)到的效果以及我的標(biāo)注:

先分析一下我們的標(biāo)注。
首先我要求每個(gè)視圖離頁面兩邊的距離都為37.5。在標(biāo)注里我很明確地說明了這個(gè)問題。
其次,我要求每個(gè)視圖之間的距離,包括視圖離頁面頂端和底端的距離都要一樣,為40。在標(biāo)注中我也很明確地說明了這一點(diǎn)。
最后,我要求每個(gè)視圖的寬度和高度要一樣。在標(biāo)注里,每個(gè)視圖的高度都標(biāo)了169,符合我一樣高度的要求。我給第一個(gè)視圖標(biāo)上了寬度300,其他兩個(gè)和第一個(gè)首尾對(duì)齊,也是300,符合我一樣寬度的要求。
乍一看這個(gè)標(biāo)注沒有問題。但是這里我們確忽略了一個(gè)很重要的問題。這個(gè)圖我是以iPhone6的尺寸來設(shè)計(jì)的,但是實(shí)際情況,它并不只會(huì)出現(xiàn)在iPhone6的屏幕上。按照上面的標(biāo)注,標(biāo)注的總寬度 = 37.5*2 + 300 = iPhone6的屏幕寬度(375)。但是如果換一個(gè)手機(jī)屏幕,這個(gè)等式就不成立了。同樣,高度也是這個(gè)問題。這樣就和實(shí)際情況產(chǎn)生了沖突。
Tips:當(dāng)你的標(biāo)注在寬度方向,或高度方向的數(shù)值加起來等于某一個(gè)具體的屏幕尺寸時(shí),你就需要去重新去檢查你的標(biāo)注了,需要說明那些尺寸是固定的,哪些尺寸是可變的。
顯然,工程師無法滿足你標(biāo)注的所有尺寸要求。如果他只看到你給的標(biāo)注文件,而不知道你的三點(diǎn)要求。那么這個(gè)標(biāo)注在寬度方向大概就出現(xiàn)了以下幾種可能性:
1.保持兩邊各37.5的邊距(margin)要求,每個(gè)視圖的寬度根據(jù)屏幕的寬度來伸縮
2.每個(gè)視圖的寬度保持300不變,兩邊的邊距根據(jù)屏幕的寬度來伸縮
3.視圖的寬度和邊距隨著屏幕的寬度變化一起縮放
從我們之前的要求來看,我們希望的是第一種可能性的,只是我們的標(biāo)注沒有很好的說明這個(gè)點(diǎn)。工程師需要靠自己的理解來選擇其中一種,有時(shí)候他的選擇可能并不是我們想要的結(jié)果。
我們該如何標(biāo)注,來很好的表達(dá)我的要求?正確的標(biāo)注應(yīng)該是這樣的:

首先,我去掉了寬度的標(biāo)注,就像上個(gè)例子說的一樣,我們需要AutoLayout自己來計(jì)算出它的寬度,也就意味著我們是希望每個(gè)視圖的寬度隨著屏幕的寬度變化而變化。其次,我去掉高度的具體數(shù)值,只標(biāo)了一個(gè)h。同樣,因?yàn)槠聊坏母叨仁遣还潭ǖ?,所以我無法給出具體的高度,但是我又要求每個(gè)視圖的高度是一樣的。通過給每個(gè)視圖標(biāo)注高度h,來表示他們的高度一樣。
之前我說過,我第一次給出的標(biāo)注大概可以有三種不同的理解,那么我們又該如何來表達(dá)這三種可能性呢?下面我就來說一下,如何使用AutoLayout的方式標(biāo)注,來很明確地來表現(xiàn)以上三種可能性。

第一個(gè)視圖的標(biāo)注,保持兩邊各37.5的邊距(margin)要求,每個(gè)視圖的寬度根據(jù)屏幕的寬度來伸縮,這個(gè)上面說過。
第二個(gè),我標(biāo)注了寬度,沒標(biāo)邊距。但是我們要求它水平方向居中,通過這個(gè)約束來確定它水平方向的位置。這樣邊距就可以根據(jù)屏幕的寬度變化而變化。
第三個(gè),我標(biāo)注了寬度為80%的屏幕寬度,這樣它就能做到和屏幕一起縮放。

我在Xcode上添加好了上面要求的約束,并選擇在不同的模擬器上運(yùn)行。這樣就可以看到我們設(shè)計(jì)的頁面在不同設(shè)備上運(yùn)行的效果了。以下就是它在不同屏幕尺寸下顯示的效果:

可以看到,在iPhone6上一模一樣的三個(gè)視圖,應(yīng)為我們設(shè)置了不同的約束,在不同的設(shè)備上運(yùn)行就出現(xiàn)了不一樣的效果。因?yàn)锳utoLayout是根據(jù)你設(shè)置的約束,自動(dòng)計(jì)算出的你定義的視圖的位置和大小。
為了適配更多的屏幕,我們在設(shè)計(jì)的時(shí)候需要用相對(duì)定位的思維來布局。
這次就講到這里,下一篇我會(huì)介紹更多AutoLayout相關(guān)知識(shí),以及如何使用Xcode來添加約束,做出你自己設(shè)計(jì)的頁面。
Via: DDC
]]>