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

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


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


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

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

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

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

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

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

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

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

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

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

因為支持按鈕只有一次點擊機會,所以當支持按鈕點擊過后它就變成不可點擊狀態(tài),它的使命也就完成了。

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

這樣初始狀態(tài)時,因為第二個約束并不是必須滿足的,所以一開始是被舍棄的。但是當支持按鈕被移除后,這個新加的按鈕正好能派上用處。這樣頁面就變成了這樣:

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

下面再看一個實際情況。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

接下來就到了添加約束的時候了,最常用的是右下角的四個按鈕,這次會用到后三個。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

下面就是它不同設備上的運行效果。


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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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