iOS支持的設備現在已經具備了不少的尺寸,針對這些不一樣的尺寸每個都作一個獨立的APP確定是不現實的,因而蘋果在iOS8以後推出了autolayout和sizeclass,同時還有VFL界面設計語言app
先說一下iOS屏幕的旋轉,首先,對於開發者而言,關注的並非屏幕的像素,而是一個點的概念,也就是說,尺寸相同的設備,不一樣的分辨率,開發者認爲他們的點是相同的,系統底層負責將一個點與對應的像素關聯起來,例如ipad普通的屏幕像素爲1024*768,而retina的屏幕像素爲2048*1536,可是他們的屏幕尺寸是同樣的,因此對點而言,依然是1024*268個點,只是retina的每個點對應四個像素,普通的一個點對應一個像素.函數
在屏幕旋轉的時候,通常而言,界面也會跟着旋轉,那麼就會形成UI的變形,由於大部分的設備不是正方形,這個時候,就必須制定旋轉的規則,不然旋轉出來的界面會丟失UI或者極其難看,這個時候,就有三種方式來管理規則,UI建立約束,代碼制定約束,或者乾脆作幾套UI.工具
在建立的iOS配置中,能夠指定app支持的約束,在以下位置佈局
portrait 正常豎直狀態 landscape left 左轉 landscape right 右轉spa
打開此處自後就默認打開了旋轉,可是還須要在代碼中指定支持旋轉的方向,在view對應的類文件中實現繼承至父類的方法supportedInterfaceOrientations,返回一個NSUinteger的,具體代碼以下.net
- (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskPortrait; }
返回的參數是宏進行或運算自後的結果,當這個方法被調用以後,若是支持這個方向的旋轉,那麼系統就會發出消息,進行這個方向的旋轉設計
接下來支持旋轉以後,就要進行UI的設計,使其能適配旋轉,關於autolayout的相關知識和操做請參考這個網頁3d
http://blog.csdn.net/pucker/article/details/41832939
重點在於autolayout容許開發者在界面上的任意兩個視圖之間創建精確的線性變化規則。所謂線性變化就是數學中的一次函數,即:code
y = m*x + corm
其中x和y是界面中任意兩個視圖的某個佈局屬性,m爲比例係數,c爲常量。
http://blog.csdn.net/pucker/article/details/41843511
該文章重點在於
經過這個比例關係,就能得出控件與控件之間的關係
另外還有一個注意點
當使用自動佈局爲Scroll View添加約束時,除了須要肯定ScrollView自己的位置尺寸以外,還須要明確ScrollView的ContentSize大小。對於上述例子,Scroll View自己會佔用下半部分屏幕,可是其ContentSize的大小是不肯定的,因此會出現異常滾動效果。所以咱們還須要爲兩個Label肯定寬高,這樣才能計算出ContentSize。按住Command鍵,在文檔結構窗口中選中Logo Image、Name Label與Description Label,點擊Pin按鈕,在彈出的窗口中選中Equal Width,這樣就使得兩個Label的寬度總與Image View的寬度相等,即Scroll View的ContentSize的寬度老是和Scroll View自己的寬度相同,所以就不會出現橫向滾動的狀況了
到這裏,自動約束就說完了,還要記得,採用直接按住control拉動控件的方式創建的約束是按照當前控件狀態創建的約束,是須要本身再去手動調整的
以上是使用IB工具進行autolayout,還可使用代碼進行autolayout
具體參考該網頁
http://blog.csdn.net/pucker/article/details/45070955
主要描述了幾個類
NSLayoutConstraint 主要用來描述約束的形式
NSLayoutAttribute 枚舉對其的格式
NSLayoutRelation layout的關係式
還有這麼一段須要注意
蘋果在iOS 6當中引入了自動佈局的新概念,但在那時仍然有不少舊的代碼使用autoresizingMask與setFrame:的方式構建界面。試想,若是將一個已經設置好frame並使用autoresizingMask的視圖添加到一個使用自動佈局的視圖中時,運行時須要隱式地將前者的frame和autoresizingMask轉化爲自動佈局約束(這些隱式轉換的約束的類型爲NSAutoresizingMaskLayoutConstraint),這樣才能明確其位置與尺寸而不會致使約束的缺失。這個隱式轉換的過程,是由UIView的translatesAutoresizingMaskIntoConstraints屬性的值決定的。默認狀況下,該值爲YES,表示須要運行時自動進行隱式轉換。這對於兼容舊的代碼固然是好的,然而當咱們明確爲視圖添加了約束後,咱們就不但願再進行autoresizingMask的隱式轉換了,不然就會引發約束的衝突。所以,須要特別注意的是,當咱們使用代碼建立視圖時,須要將translatesAutoresizingMaskIntoConstraints屬性的值設置爲NO
這樣就能夠用代碼的方式來設定界面的layout屬性了
可是使用這種辦法顯得比較繁瑣,接下來能夠用VFL語言來進行layout管理,參考的網頁爲
http://blog.csdn.net/pucker/article/details/45093483
VFL是一種建立約束的新的形式,實際上建立的依然是NSLayoutConstraint對象,只是生成該對象的方式更加的簡單
簡單的規則以下
參數format是一個符合VFL語法的字符串。上述代碼中的H:表示本VFL字符串描述的是水平方向的約束,與之相對的是V:表示垂直方向。若是VFL字符串沒有指明H:仍是V:,則默認爲水平方向。|表示父視圖。VFL要求全部視圖的名字必須放在中括號以內,[logoImageView]指代的就是logoImageView。-0-表示的是間距值爲0。 因此@」H:|-0-[logoImageView]-0-|」表示在水平方向上,logoImageView左側與其父視圖左側的間距爲0,logoImageView右側與其父視圖右側的間距爲0。@」V:|-0-[logoImageView]」表示在垂直方向上,logoImageView頂部與其父視圖頂部的間距爲0。 另外說一句,-0-能夠不寫,也就是說若是間距爲0則不用明確寫出,因此@」H:|-0-[logoImageView]-0-|」能夠精簡爲@」H:|[logoImageView]|」,@」V:|-0-[logoImageView]」能夠精簡爲@」V:|[logoImageView]」
另外,這種辦法並非萬能的,有下面的注意點
VFL並不能表達全部的約束,例如「logoImageView高度爲父視圖高度一半」這樣的具備比例關係的約束,就沒法使用VFL表達出來,因此這時咱們只能直接建立NSLayoutConstraint實例了,就像上面的代碼那樣。
好了,約束的大部分類容就是這些,相信看完那三個網頁基本上佈局也就沒什麼難度了.關鍵仍是在那個公式y=ax+b,掌握這個公式的具體意義,就能知道參數的設置,佈局就是體力活了.