三十而立,從零開始學ios開發(八):Autorotation and Autosizing


不好意思,這一篇間隔的時間有點長,最近實在是事情太多,耽擱了,好了,長話短說,下面繼續學習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個常量用來做判斷

UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight

當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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM