iOS应用横竖屏切换
生活随笔
收集整理的這篇文章主要介紹了
iOS应用横竖屏切换
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、概述: ? ? 在iOS應用中,由UIViewController來控制屏幕翻轉,根據需要隨設備方向自動切換。在iOS6和之前的系統之間,控制方法發生了些變化。
二、視圖伸縮屬性:
1.UIView類的autoresizingMask屬性,用來指定當它的父視圖frame發生變化時,自身frame的變化規則。此屬性可以在XIB中設置,也可以直接用代碼設置,具體用哪個看情況。可用值的具體含義如下: ? ?(1)UIViewAutoresizingNone:自身frame不隨父視圖變化; ? ?(2)UIViewAutoresizingFlexibleLeftMargin:父視圖frame發生變化時,自身視圖的左邊距動態縮小或者拉伸; ? ?(3)UIViewAutoresizingFlexibleRightMargin:父視圖frame發生變化時,自身視圖的右邊距動態縮小或者拉伸; ? ?(4)UIViewAutoresizingFlexibleTopMargin:父視圖frame發生變化時,自身視圖的上邊距動態縮小或者拉伸; ? ?(5)UIViewAutoresizingFlexibleBottomMargin:父視圖frame發生變化時,自身視圖的下邊距動態縮小或者拉伸; ? ?(6)UIViewAutoresizingFlexibleWidth:父視圖frame發生變化時,自身視圖寬度隨父視圖同比例動態縮小或者拉伸; ? ?(7)UIViewAutoresizingFlexibleHeight:父視圖frame發生變化時,自身視圖高度隨父視圖同比例動態縮小或者拉伸;
2.伸縮屬性可以多個一起使用,使用位或運算符("|")連接。
3.在屏幕翻轉之后,控制器的主視圖的frame會發生變化,所以,在屏幕翻轉之后的界面調整中,可能會用到這個屬性來控制子界面的frame。
三、Info.plist中相關的設置: Supported interface orientations,對應一個數組,包含應用支持的設備方向。如果代碼中實現了沒有支持的方向,執行時會報異常。
四、UIViewController中的翻轉控制方法(iOS6之前)
1.判斷是否支持新方向: (1)實現視圖控制器類的shouldAutorotateToInterfaceOrientation:方法,在此方法中,如果當前設備方向為我們需要支持的方向,則該方法返回YES,否則返回NO。系統會根據此方法返回的BOOL值來決定是不是翻轉該控制器的界面。 (2)可用的設備方向值如下: ? ?UIInterfaceOrientationPortrait:Home鍵在下方; ? ?UIInterfaceOrientationPortraitUpsideDown:Home鍵在上方; ? ?UIInterfaceOrientationLandscapeLeft:Home鍵在左方: ? ?UIInterfaceOrientationLandscapeRight:Home鍵在右方。 (3)此方法默認實現只支持UIInterfaceOrientationPortrait。
2.翻轉通知方法: ? ?(1)控制器類翻轉通知分為兩類,一類是一步翻轉通知,一類是兩步翻轉通知。 ? ?(2)控制器默認選擇使用一步翻轉過程,如果同時重寫了兩步翻轉通知方法,則控制器會自動選擇使用兩步翻轉過程。
3.一步翻轉通知方法: (1)視圖控制器類的willRotateToInterfaceOrientation:duration:方法,在控制器視圖將要翻轉時被調用。 ? ? 如果視圖翻轉時界面變化相對簡單,可以在XIB中使用伸縮屬性來設置子界面變化。如果在翻轉之后界面變化比較復雜,伸縮屬性就無能為力了,需要在此方法中用代碼動態設置需要調整的子視圖的frame。在改變子視圖frame時,為了使翻轉效果更友好,應該使用動畫API,使frame調整過程更優美,動畫執行時長使用duration參數對應的值。 (2)視圖控制器類的didRotateFromInterfaceOrientation:方法,在控制器視圖翻轉完畢時調用。 ? ? 我們可以在此方法中做一些必要的動作。 ? ? 不要在此方法中調整子視圖frame,否則子視圖的界面frame調整會比主視圖慢一小段時間,效果不好。
4.兩步翻轉通知方法: (1)視圖控制器類的willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:方法,當視圖控制器前半部分翻轉開始時調用。假如我們想要在翻轉前半部分開始時添加額外的動畫,可以重寫此方法。 (2)視圖控制器類的didAnimateFirstHalfOfRotationToInterfaceOrientation: 方法,當控制器前半部分翻轉完成時調用。 (3)視圖控制器類的willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:方法,當控制器后半部分翻轉開始時調用。 (4)兩步翻轉方法在iOS5版本開始被廢棄。
5.具體的執行流程: (1)一步翻轉流程圖:
(2)兩步翻轉流程圖:
五、iOS6之前使用翻轉通知方法碰到的問題
1.情景簡述:假如視圖A,初始實現是豎屏的,而且支持所有設備方向,然后在進入視圖A時,設備是橫屏的,如果視圖A是主視圖,willRotateToInterfaceOrientation:duration:會被調用,但是如果視圖A不是主視圖,則不會調用,導致進入視圖A之后,視圖A的子視圖還是豎向的狀態。但是接下來真實的翻轉設備到豎屏,再到橫屏,willRotateToInterfaceOrientation:duration:就會被調用了。
2.分析原因: (1)控制器初始化時,只有主視圖能夠收到翻轉通知。但是真實的翻轉設備時,已經初始化的所有視圖都能收到翻轉通知。主視圖包含真實添加到window的控制器視圖、通過presentModalViewController彈出的視圖,以及導航控制器的第一個視圖(之后push進的視圖不是主視圖)等。 (2)假如我們要寫一個用導航控制器組織的App,但是每個界面都需要支持橫屏和豎屏,就遇到上面的問題了。
3.解決方法: (1)原理:重寫UIView的layoutSubviews方法,當界面初始化,屏幕旋轉導致重繪,都會調用此方法。 (2)實現方法:首先實現UIView的一個子類,比如取名為RotationView,并建立一個代理對象;重寫layoutSubviews方法,通過檢查狀態欄方向是不是和之前記錄的方向一致,如果不一致,則調用代理方法;然后將控制器的view屬性修改為RotationView,將RotationView的代理設置為控制器本身,在代理方法實現中,根據當前設備方向,重新設置子視圖frame。 (3)此方法具有通用性。
4.iOS6及以后,上面提到的問題就不存在了。但是會碰到新的問題,具體介紹下小節介紹。
六、UIViewController中的翻轉控制方法(iOS6以以后)
1.視圖控制器類的shouldAutorotateToInterfaceOrientation:被廢棄,增加了三個新的方法來實現這個方法的功能。 (1)shouldAutorotate:返回BOOL值,告訴控制器要不要支持翻轉。 (2)supportedInterfaceOrientations:如果支持翻轉,則告訴控制器要支持的設備方向。 ? ? 返回值類型為NSUInteger,通過UIInterfaceOrientationMaskXXX值之間的位或運算獲得。 ? ? 此方法的默認返回值為:iPad--UIInterfaceOrientationMaskAll,iPhone--UIInterfaceOrientationMaskAllButUpsideDown。 (3)preferredInterfaceOrientationForPresentation:通知控制器通過present方法導入的控制器視圖支持的方向。 ? ? 返回值為類型為UIInterfaceOrientation,也就是說此方法只支持返回一個方向。蘋果文檔的說明:當你的主界面支持兩個及以上的方向,但是希望通過present彈出的界面只支持一個方向,則重寫這個方法。如果不重寫這個方法,此方法會默認返回狀態欄所處的方向。
2.其它翻轉控制的方法,兩步翻轉不能用了,一步翻轉和之前一樣。
3.supportedInterfaceOrientations的調用時機: (1)當用戶改變設備方向時,系統會調用此方法,但是只針對window的主視圖或者推進類視圖的頂層視圖的控制器,比如導航控制器的非頂層視圖的此方法默認是不起作用的。 (2)只有shouldAutorotate返回YES時才會被調用。
4.額外操作: (1)由于supportedInterfaceOrientations的調用時機發生了變化,所以,如果我們需要讓當前顯示視圖來控制整體方向,需要做一些額外的操作來處理這個問題。 (2)假如window的主視圖是UIViewController類,則直接重寫上面的方法,返回相應支持的方向即可。 (3)假如window的主視圖是導航控制器,則需要重寫它,讓上面的三個方法返回topViewController對應方法的返回值,即由當前顯示的視圖來控制整體方向。比較好的實現是使用類別的方式。 (4)加入window的主視圖是選項卡控制器,則需要重寫它,讓上面的三個方法返回selectedViewController對應方法的返回值,即由當前選擇視圖來控制整體方向,如果selectedViewController為一個導航控制器,則導航控制器又會找到其topViewController返回的值。也就是說,這是一個迭代取值的過程。
二、視圖伸縮屬性:
1.UIView類的autoresizingMask屬性,用來指定當它的父視圖frame發生變化時,自身frame的變化規則。此屬性可以在XIB中設置,也可以直接用代碼設置,具體用哪個看情況。可用值的具體含義如下: ? ?(1)UIViewAutoresizingNone:自身frame不隨父視圖變化; ? ?(2)UIViewAutoresizingFlexibleLeftMargin:父視圖frame發生變化時,自身視圖的左邊距動態縮小或者拉伸; ? ?(3)UIViewAutoresizingFlexibleRightMargin:父視圖frame發生變化時,自身視圖的右邊距動態縮小或者拉伸; ? ?(4)UIViewAutoresizingFlexibleTopMargin:父視圖frame發生變化時,自身視圖的上邊距動態縮小或者拉伸; ? ?(5)UIViewAutoresizingFlexibleBottomMargin:父視圖frame發生變化時,自身視圖的下邊距動態縮小或者拉伸; ? ?(6)UIViewAutoresizingFlexibleWidth:父視圖frame發生變化時,自身視圖寬度隨父視圖同比例動態縮小或者拉伸; ? ?(7)UIViewAutoresizingFlexibleHeight:父視圖frame發生變化時,自身視圖高度隨父視圖同比例動態縮小或者拉伸;
2.伸縮屬性可以多個一起使用,使用位或運算符("|")連接。
3.在屏幕翻轉之后,控制器的主視圖的frame會發生變化,所以,在屏幕翻轉之后的界面調整中,可能會用到這個屬性來控制子界面的frame。
三、Info.plist中相關的設置: Supported interface orientations,對應一個數組,包含應用支持的設備方向。如果代碼中實現了沒有支持的方向,執行時會報異常。
四、UIViewController中的翻轉控制方法(iOS6之前)
1.判斷是否支持新方向: (1)實現視圖控制器類的shouldAutorotateToInterfaceOrientation:方法,在此方法中,如果當前設備方向為我們需要支持的方向,則該方法返回YES,否則返回NO。系統會根據此方法返回的BOOL值來決定是不是翻轉該控制器的界面。 (2)可用的設備方向值如下: ? ?UIInterfaceOrientationPortrait:Home鍵在下方; ? ?UIInterfaceOrientationPortraitUpsideDown:Home鍵在上方; ? ?UIInterfaceOrientationLandscapeLeft:Home鍵在左方: ? ?UIInterfaceOrientationLandscapeRight:Home鍵在右方。 (3)此方法默認實現只支持UIInterfaceOrientationPortrait。
2.翻轉通知方法: ? ?(1)控制器類翻轉通知分為兩類,一類是一步翻轉通知,一類是兩步翻轉通知。 ? ?(2)控制器默認選擇使用一步翻轉過程,如果同時重寫了兩步翻轉通知方法,則控制器會自動選擇使用兩步翻轉過程。
3.一步翻轉通知方法: (1)視圖控制器類的willRotateToInterfaceOrientation:duration:方法,在控制器視圖將要翻轉時被調用。 ? ? 如果視圖翻轉時界面變化相對簡單,可以在XIB中使用伸縮屬性來設置子界面變化。如果在翻轉之后界面變化比較復雜,伸縮屬性就無能為力了,需要在此方法中用代碼動態設置需要調整的子視圖的frame。在改變子視圖frame時,為了使翻轉效果更友好,應該使用動畫API,使frame調整過程更優美,動畫執行時長使用duration參數對應的值。 (2)視圖控制器類的didRotateFromInterfaceOrientation:方法,在控制器視圖翻轉完畢時調用。 ? ? 我們可以在此方法中做一些必要的動作。 ? ? 不要在此方法中調整子視圖frame,否則子視圖的界面frame調整會比主視圖慢一小段時間,效果不好。
4.兩步翻轉通知方法: (1)視圖控制器類的willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:方法,當視圖控制器前半部分翻轉開始時調用。假如我們想要在翻轉前半部分開始時添加額外的動畫,可以重寫此方法。 (2)視圖控制器類的didAnimateFirstHalfOfRotationToInterfaceOrientation: 方法,當控制器前半部分翻轉完成時調用。 (3)視圖控制器類的willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:方法,當控制器后半部分翻轉開始時調用。 (4)兩步翻轉方法在iOS5版本開始被廢棄。
5.具體的執行流程: (1)一步翻轉流程圖:
(2)兩步翻轉流程圖:
五、iOS6之前使用翻轉通知方法碰到的問題
1.情景簡述:假如視圖A,初始實現是豎屏的,而且支持所有設備方向,然后在進入視圖A時,設備是橫屏的,如果視圖A是主視圖,willRotateToInterfaceOrientation:duration:會被調用,但是如果視圖A不是主視圖,則不會調用,導致進入視圖A之后,視圖A的子視圖還是豎向的狀態。但是接下來真實的翻轉設備到豎屏,再到橫屏,willRotateToInterfaceOrientation:duration:就會被調用了。
2.分析原因: (1)控制器初始化時,只有主視圖能夠收到翻轉通知。但是真實的翻轉設備時,已經初始化的所有視圖都能收到翻轉通知。主視圖包含真實添加到window的控制器視圖、通過presentModalViewController彈出的視圖,以及導航控制器的第一個視圖(之后push進的視圖不是主視圖)等。 (2)假如我們要寫一個用導航控制器組織的App,但是每個界面都需要支持橫屏和豎屏,就遇到上面的問題了。
3.解決方法: (1)原理:重寫UIView的layoutSubviews方法,當界面初始化,屏幕旋轉導致重繪,都會調用此方法。 (2)實現方法:首先實現UIView的一個子類,比如取名為RotationView,并建立一個代理對象;重寫layoutSubviews方法,通過檢查狀態欄方向是不是和之前記錄的方向一致,如果不一致,則調用代理方法;然后將控制器的view屬性修改為RotationView,將RotationView的代理設置為控制器本身,在代理方法實現中,根據當前設備方向,重新設置子視圖frame。 (3)此方法具有通用性。
4.iOS6及以后,上面提到的問題就不存在了。但是會碰到新的問題,具體介紹下小節介紹。
六、UIViewController中的翻轉控制方法(iOS6以以后)
1.視圖控制器類的shouldAutorotateToInterfaceOrientation:被廢棄,增加了三個新的方法來實現這個方法的功能。 (1)shouldAutorotate:返回BOOL值,告訴控制器要不要支持翻轉。 (2)supportedInterfaceOrientations:如果支持翻轉,則告訴控制器要支持的設備方向。 ? ? 返回值類型為NSUInteger,通過UIInterfaceOrientationMaskXXX值之間的位或運算獲得。 ? ? 此方法的默認返回值為:iPad--UIInterfaceOrientationMaskAll,iPhone--UIInterfaceOrientationMaskAllButUpsideDown。 (3)preferredInterfaceOrientationForPresentation:通知控制器通過present方法導入的控制器視圖支持的方向。 ? ? 返回值為類型為UIInterfaceOrientation,也就是說此方法只支持返回一個方向。蘋果文檔的說明:當你的主界面支持兩個及以上的方向,但是希望通過present彈出的界面只支持一個方向,則重寫這個方法。如果不重寫這個方法,此方法會默認返回狀態欄所處的方向。
2.其它翻轉控制的方法,兩步翻轉不能用了,一步翻轉和之前一樣。
3.supportedInterfaceOrientations的調用時機: (1)當用戶改變設備方向時,系統會調用此方法,但是只針對window的主視圖或者推進類視圖的頂層視圖的控制器,比如導航控制器的非頂層視圖的此方法默認是不起作用的。 (2)只有shouldAutorotate返回YES時才會被調用。
4.額外操作: (1)由于supportedInterfaceOrientations的調用時機發生了變化,所以,如果我們需要讓當前顯示視圖來控制整體方向,需要做一些額外的操作來處理這個問題。 (2)假如window的主視圖是UIViewController類,則直接重寫上面的方法,返回相應支持的方向即可。 (3)假如window的主視圖是導航控制器,則需要重寫它,讓上面的三個方法返回topViewController對應方法的返回值,即由當前顯示的視圖來控制整體方向。比較好的實現是使用類別的方式。 (4)加入window的主視圖是選項卡控制器,則需要重寫它,讓上面的三個方法返回selectedViewController對應方法的返回值,即由當前選擇視圖來控制整體方向,如果selectedViewController為一個導航控制器,則導航控制器又會找到其topViewController返回的值。也就是說,這是一個迭代取值的過程。
總結
以上是生活随笔為你收集整理的iOS应用横竖屏切换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ECC椭圆曲线加密算法原理
- 下一篇: 田野中科院计算机网络信息中心,中国科学院