不好意思,這一篇間隔的時間有點長,最近實在是事情太多,耽擱了,好了,長話短說,下面繼續學習ios。
這次學習的內容是Autorotation和Autosizing,Autorotation就是螢幕內容自動旋轉,因為iphone有重力感應系統(陀螺儀???),螢幕的內容會隨著使用者手握iphone的方式(豎著握Portrait、橫著握Landscape)而改變,這個相信大家都已經有所體會,Autosizing是指當iphone的旋轉螢幕後,螢幕裡面控制項的大小和位置也會自動改變。好了,下面跟著例子繼續學習。
1)建立一個Single View項目,並命名為Autosize。
2)配置app所支援的旋轉方向
當完成一個項目建立後,預設狀態下,在Project Navigator中,會選中項目的根節點,如下
當根節點選中後,在其右側Summary tab中找到叫做“Supported Device Orientations”(裝置所支援的方向)的地區,在這個地區中,就是用來設定iphone所支援的旋轉方向的。
可以看到,一共有4個方向(其實也只有這4個方向),根據進行設定,在我們的這個例子中,就保持預設狀態即可,一般情況下,app很少會去選擇“Upside Down”,一般來說很少有人會倒著拿手機,除了有特殊情況外。
除了上面的方法可以設定app支援的旋轉方向外,還有一個地方可以設定,在Project Navigator中的“Supporting Files”下,選中Autosize-Info.plist。
然後找到“Supported interface Orientations”並展開,會看到3個Item,分別對應剛才圖中選中的三個旋轉方向
如果想要添加一個新的方向,只要滑鼠放在某一個Item上,在這個Item的右邊會有一個加號和一個減號,點擊加號增加一個Item,點擊減號刪除一個Item。
可以隨意添加或者刪除裡面的Item,然後在回到Summary tab中看,Summary tab中的“Supported Device Orientations”會隨之改變,這兩個地方是保持聯動的,其實xxx-Info.plist和Summary tab是同一個東西,只是顯示的方法不同,Summary tab使用圖形介面控制,xxx-Info.plist使用文字。
3)代碼中判斷app是否支援某種旋轉方向
在BIDViewController.m中,有一個預設的方法叫做shouldAutorotateToInterfaceOrientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);}
當支援某種旋轉方向時,返回YES,不支援返回NO,ios為4個旋轉方向分別定義了4個常量用來做判斷
UIInterfaceOrientationPortraitUIInterfaceOrientationPortraitUpsideDownUIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRight
當iphone改變當前的方向時,首先會調用到該方法進行判斷,判斷app是否支援當前的方向,如果支援返回YES,則繼續執行旋轉操作,如果不支援,則返回NO,接下來的操作就不繼續進行了。(但是這裡有個問題,到底是以shouldAutorotateToInterfaceOrientation判斷為準還是以Supported Device Orientations中設定的旋轉方向為準的?這個在本篇的最後我會去做一個實驗驗證一下。)
4)添加6個button
選中BIDViewController.xib,如添加6個button並命名,6個button分別位於左上、左中、左下、右上、右中、右下
(2種添加按鈕的方法:一,一個一個從object library拖進來;二,先從object library中拖進來一個,然後按住option鍵,滑鼠點擊一個按鈕不放並拖動,就可以複製一個按鈕了。)
5)編譯運行,測試旋轉效果
啟動時的預設效果
旋轉(選擇菜單Hardware->Rotate Left或者command+>)後效果
問題出來了,旋轉螢幕後,按鈕是旋轉了,但是相對位置(相對於螢幕左邊和頂部的距離)沒有改變,因此除了"UL"button之外,其他所有的button的位置都是不對的,更何況LL和LR兩個button不見了!解決這個問題的方法就是是Autosizing。
6)使用Autosize屬性
還是選則BIDViewController.xib,然後選中UL按鈕,使用快速鍵command+5,開啟size inspector(就在attributes inspector的右邊,你也可以直接用滑鼠去選)
從中可以看到Autosizing屬性是一個由兩個正方形組成的圖
大的一個正方形表示iphone螢幕的4條邊,中間小的正方形表示對象自己,我們選中的是UL按鈕,則中間小的正方形就表示UL按鈕。然後在小正方形和大正方形之間,有4個“工”,分別表示當前對象距離iphone螢幕4條邊的距離是否發生改變,選中表示固定不變(在我們的這個例子中,需要用這個特性來固定按鈕的相對位置)。小正方形中間的十字表示是否上下、左右進行展開(在我們的這個例子中,這個特性按時不用,不過自己可以試試看)。
(在Autosizing的右邊,有一個Example圖,當滑鼠移動到Autosizing這塊地區上時,裡面會動態呈現當前對象相對位置狀況,方便設定屬性。)
根據上面的描述,我們分別設定6個按鈕的Autosizing如下
(此圖截於pdf,因此不太清晰)
UL:固定左邊和上邊
UR:固定上邊和右邊
L:固定左邊
R:固定右邊
LL:固定左邊和下邊
LR:固定下邊後右邊
7)再次編譯運行,測試旋轉效果
是iphone橫過來時的效果
所有的按鈕都各司其位,達到了我們想要的效果。
Autosize_1
8)問題再次出現
我們好不容易將旋轉後按鈕位置的問題搞定,新的問題又出現了,我們將6個按鈕的大小都設定成125*125(同時選中6個按鈕,在Size inspector中設定Width=125,Height=125,然後重新調整6個按鈕的位置),如下
編譯運行,並旋轉螢幕,問題出現了
按鈕疊加在了一起,對於這個問題,我們再怎麼調整Autosizing屬性,都是無法解決的,因為按鈕過大,所以在螢幕橫過來的時候,無法很好的擺放其位置,解決這個問題的方法是寫代碼,當iphone旋轉時,改變按鈕位置。
9)建立Outlet
這個工作應該已經很熟悉了,分別為6個按鈕建立Outlet,建立完成後的BIDViewController.h代碼如下
#import <UIKit/UIKit.h>@interface BIDViewController : UIViewController@property (strong, nonatomic) IBOutlet UIButton *buttonUL;@property (strong, nonatomic) IBOutlet UIButton *buttonUR;@property (strong, nonatomic) IBOutlet UIButton *buttonL;@property (strong, nonatomic) IBOutlet UIButton *buttonR;@property (strong, nonatomic) IBOutlet UIButton *buttonLL;@property (strong, nonatomic) IBOutlet UIButton *buttonLR;@end
10)在BIDViewController.m中重載willAnimateRotationToInterfaceOrientation方法
willAnimateRotationToInterfaceOrientation發生在一個旋轉寄生之後且旋轉動畫還未發生之前(好吧,旋轉的細節我還不是很清楚,但是可知的是,一定有一個事件是發生在旋轉開始後還未結束前的,且旋轉是有動畫的,而這個事件就是發生在旋轉開始後,且旋轉動畫還未開始之前的那段時間裡面),會被自動調用。完整code如下
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) { buttonUL.frame = CGRectMake(20, 20, 125, 125); buttonUR.frame = CGRectMake(175, 20, 125, 125); buttonL.frame = CGRectMake(20, 168, 125, 125); buttonR.frame = CGRectMake(175, 168, 125, 125); buttonLL.frame = CGRectMake(20, 315, 125, 125); buttonLR.frame = CGRectMake(175, 315, 125, 125); } else { buttonUL.frame = CGRectMake(20, 20, 125, 125); buttonUR.frame = CGRectMake(20, 155, 125, 125); buttonL.frame = CGRectMake(177, 20, 125, 125); buttonR.frame = CGRectMake(177, 155, 125, 125); buttonLL.frame = CGRectMake(328, 20, 125, 125); buttonLR.frame = CGRectMake(328, 155, 125, 125); }}
稍微解釋一下,frame屬性是用來描述當前視圖在其父視圖中的位置和大小,buttonUL.frame就是用來描述該button在其父視圖(View)中的位置和大小,其中位置是CGPoint,大小是CGSize,他們在ios中的聲明是這樣的
struct CGPoint { CGFloat x; CGFloat y; }; typedef struct CGPoint CGPoint; struct CGSize { CGFloat width; CGFloat height; }; typedef struct CGSize CGSize;
很容易理解。在ios中還有一個類型將CGPoint和CGSize組合在一起,這個就是CGRect
struct CGRect { CGPoint origin; CGSize size; }; typedef struct CGRect CGRect;
上面代碼中的buttonUL.frame = CGRectMake(20, 20, 125, 125)就是用來設定buttonUL在其父視圖(View)中的位置,CGRectMake中前2個參數其實是CGPoint,buttonUL的左上方的起始點,後兩個參數其實是CGRect,設定buttonUL的高和寬。
編譯運行旋轉
當iphone旋轉後,6個按鈕的位置還是擺放的很合適,good!
11)shouldAutorotateToInterfaceOrientation判斷為準還是以Supported Device Orientations判斷為準
本篇文章中所有的開發都已經完成,最後對這個遺留問題做一個實驗,看看到底是以什麼為準,開啟BIDViewController.m,修改shouldAutorotateToInterfaceOrientation方法如下
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown && interfaceOrientation != UIInterfaceOrientationLandscapeLeft);}
當interfaceOrientation的方向為UIInterfaceOrientationPortraitUpsideDown或者UIInterfaceOrientationLandscapeLeft,app的視圖都不進行改變,然後編譯運行程式,效果如下
視圖沒有變哦,通過實驗發現還是以code為準,這個在以後寫代碼的過程中應該多加留意。
12)總結
這篇內容對iphone的旋轉功能有了一個初步的認識,對iphone旋轉後,介面的布局有了一個淺顯的描述,一般來說有3種方法來改變iphone旋轉後介面需要重新布局的問題:
1、使用Autosizing
2、寫code
3、重新弄個View,替換原先的View(這個方法下一章會學習)
總的來說這次的內容還是很有用的,每個app都會遇到,除非你的app不支援旋轉。
Autosize all