你好,歡迎來到IOS教程網

 Ios教程網 >> IOS教程 >> 關於IOS教程 >> iOS開發中使用屏幕旋轉功能的相關方法

iOS開發中使用屏幕旋轉功能的相關方法

編輯:關於IOS教程

加速計是整個IOS屏幕旋轉的基礎,依賴加速計,設備才可以判斷出當前的設備方向,IOS系統共定義了以下七種設備方向:
 代碼如下:

typedef NS_ENUM(NSInteger, UIDeviceOrientation) {

    UIDeviceOrientationUnknown,

    UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom

    UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top

    UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right

    UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left

    UIDeviceOrientationFaceUp,              // Device oriented flat, face up

    UIDeviceOrientationFaceDown             // Device oriented flat, face down

};
 
   以及如下四種界面方向:
 代碼如下:

typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {

    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,

    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,

    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,

    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft

};

 
 
一、UIKit處理屏幕旋轉的流程 
 
  當加速計檢測到方向變化的時候,會發出 UIDeviceOrientationDidChangeNotification 通知,這樣任何關心方向變化的view都可以通過注冊該通知,在設備方向變化的時候做出相應的響應。上一篇博客中,我們已經提到了在屏幕旋轉的時候,UIKit幫助我們做了很多事情,方便我們完成屏幕旋轉。
 
  UIKit的相應屏幕旋轉的流程如下:
 
1、設備旋轉的時候,UIKit接收到旋轉事件。
 
2、UIKit通過AppDelegate通知當前程序的window。
 
3、Window會知會它的rootViewController,判斷該view controller所支持的旋轉方向,完成旋轉。
 
4、如果存在彈出的view controller的話,系統則會根據彈出的view controller,來判斷是否要進行旋轉。
 
 
 
二、UIViewController實現屏幕旋轉
 
  在響應設備旋轉時,我們可以通過UIViewController的方法實現更細粒度的控制,當view controller接收到window傳來的方向變化的時候,流程如下:
 
1、首先判斷當前viewController是否支持旋轉到目標方向,如果支持的話進入流程2,否則此次旋轉流程直接結束。
 
2、調用 willRotateToInterfaceOrientation:duration: 方法,通知view controller將要旋轉到目標方向。如果該viewController是一個container view controller的話,它會繼續調用其content view controller的該方法。這個時候我們也可以暫時將一些view隱藏掉,等旋轉結束以後在現實出來。
 
3、window調整顯示的view controller的bounds,由於view controller的bounds發生變化,將會觸發 viewWillLayoutSubviews 方法。這個時候self.interfaceOrientation和statusBarOrientation方向還是原來的方向。
 
4、接著當前view controller的 willAnimateRotationToInterfaceOrientation:duration: 方法將會被調用。系統將會把該方法中執行的所有屬性變化放到動animation block中。
 
5、執行方向旋轉的動畫。
 
6、最後調用 didRotateFromInterfaceOrientation: 方法,通知view controller旋轉動畫執行完畢。這個時候我們可以將第二部隱藏的view再顯示出來。
 
  整個響應過程如下圖所示:

以上就是UIKit下一個完整的屏幕旋轉流程,我們只需要按照提示做出相應的處理就可以完美的支持屏幕旋轉。
 
 
 
三、注意事項和建議
 
  1)注意事項
 
  當我們的view controller隱藏的時候,設備方向也可能發生變化。例如view Controller A彈出一個全屏的view controller B的時候,由於A完全不可見,所以就接收不到屏幕旋轉消息。這個時候如果屏幕方向發生變化,再dismiss B的時候,A的方向就會不正確。我們可以通過在view controller A的viewWillAppear中更新方向來修正這個問題。
 
  2)屏幕旋轉時的一些建議
 •在旋轉過程中,暫時界面操作的響應。
 •旋轉前後,盡量當前顯示的位置不變。
 •對於view層級比較復雜的時候,為了提高效率在旋轉開始前使用截圖替換當前的view層級,旋轉結束後再將原view層級替換回來。
 •在旋轉後最好強制reload tableview,保證在方向變化以後,新的row能夠充滿全屏。例如對於有些照片展示界面,豎屏只顯示一列,但是橫屏的時候顯示列表界面,這個時候一個界面就會顯示更多的元素,此時reload內容就是很有必要的。

IOS:屏幕旋轉與Transform
iTouch,iPhone,iPad設置都是支持旋轉的,如果我們的程序能夠根據不同的方向做出不同的布局,體驗會更好。
 
  如何設置程序支持旋轉呢,通常我們會在程序的info.plist中進行設置Supported interface orientations,添加我們程序要支持的方向,而且程序裡面每個viewController也有方法
 
  supportedInterfaceOrientations(6.0及以後)
 
  shouldAutorotateToInterfaceOrientation(6.0之前的系統)
 
  通過viewController的這些方法,我們可以做到更小粒度的旋轉控制,如程序中僅僅允許個別界面旋轉。

 
 
 
一、屏幕旋轉背後到底做了什麼呢?
 
  下面我們看個簡單的例子,用xcode新建一個默認的單視圖工程,然後在對應viewController的響應旋轉後的函數中輸出一下當前view的信息,代碼如下:
 代碼如下:

SvRotateViewController

//
//  SvRotateViewController.m
//  SvRotateByTransform
//
//  Created by  maple on 4/21/13.
//  Copyright (c) 2013 maple. All rights reserved.
//

#import "SvRotateViewController.h"

@interface SvRotateViewController ()

@end

@implementation SvRotateViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    self.view.backgroundColor = [UIColor grayColor];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    NSLog(@"UIViewController will rotate to Orientation: %d", toInterfaceOrientation);
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    NSLog(@"did rotated to new Orientation, view Information %@", self.view);
}

@end

  查看代碼我們可以發現,我們的viewController支持四個方向,然後在旋轉完成的didRotateFromInterfaceOrientation函數中打印了self.view的信息,旋轉一圈我們可以看到如下輸出:

二、什麼是Transform
 
  Transform(變化矩陣)是一種3×3的矩陣,如下圖所示:

通過這個矩陣我們可以對一個坐標系統進行縮放,平移,旋轉以及這兩者的任意組著操作。而且矩陣的操作不具備交換律,即矩陣的操作的順序不同會導致不同的結果。UIView有個transform的屬性,通過設置該屬性,我們可以實現調整該view在其superView中的大小和位置。
 
  矩陣實現坐標變化背後的數學知識:

設x,y分別代表在原坐標系統中的位置,x',y'代表通過矩陣變化以後在新的系統中的位置。其中式1就是矩陣變化的公式,對式1進行展開以後就可以得到式2。從式2我們可以清楚的看到(x,y)到(x',y')的變化關系。
 
  1)當c,b,tx,ty都為零時,x' = ax,y' = by;即a,d就分別代表代表x,y方向上放大的比例;當a,d都為1時,x' = x,y' = y;這個時候這個矩陣也就是傳說中的CGAffineTransformIdentity(標准矩陣)。
 
  2)當a,d為1,c,b為零的時候,x' = x + tx,y' = y + ty;即tx,ty分別代表x,y方向上的平移距離。
 
  3)前面兩種情況就可以實現縮放和平移了,那麼旋轉如何表示呢?
 
  假設不做平移和縮放操作,那麼從原坐標系中的一點(x,y)旋轉α°以後到了新的坐標系中的一點(x',y'),那麼旋轉矩陣如下:

展開以後就是x' = xcosα - ysinα,y' = xsinα + ycosα;
 
 
 
  實際應用中,我們將這些變化綜合起來,即可完成所有二維的矩陣變化。現在我們在回過頭來看看前面設備旋轉時的輸出,當設備位於Portrait的時候由於矩陣是標准矩陣,所以沒有進行打印。當轉到UIInterfaceOrientationLandscapeLeft方向的時候,我們的設備是順時針轉了90°(逆時針為正,順時針為負),這個時候矩陣應該是(cos-90°,sin-90°,-sin-90°,cos-90°,tx,ty),由於未進行平移操作所以tx,ty都為0,剛好可以跟我們控制台輸出:"<UIView: 0x8075390; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x8074980>>"一致。觀察其他兩個方向的輸出,發現結果均和分析一致。
 
  由此可以發現屏幕旋轉其實就是通過view的矩陣變化實現,當設備監測到旋轉的時候,會通知當前程序,當前程序再通知程序中的window,window會通知它的rootViewController的,rootViewController對其view的transform進行設置,最終完成旋轉。
 
  如果我們直接將一個view添加到window上,系統將不會幫助我們完成旋操作,這個時候我們就需要自己設置該view的transform來實現旋轉了。這種情況雖然比較少,但是也存在的,例如現在很多App做的利用狀態欄進行消息提示的功能就是利用自己創建window並且自己設置transform來完成旋轉支持的,下一篇博客會介紹如何實現這種消息通知。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved