移動設備的屏幕有限,所有的東西都需要放到一個單一窗口組成的單一界面顯示,在ios中體現為視圖切換(在《ios – 視圖》中已經說明了視圖),當一個視圖替換掉另一個視圖的時候,會經常使用動畫效果,這個任務就是交給視圖管理器來完成的。
ios5之後應用程序窗口有一個根視圖控制器(rootViewController),當不為rootViewController賦值時,會出現“Application windows are expected to have a root view controller at the end of application launch”警告。 1. 視圖控制器的實例化方式 視圖控制器的實例化也有幾種方式: 第一種: 代碼,也是我最喜歡的一種,不是因為它簡單,是因為使用代碼會使得程序的結構變得清晰簡單 更易懂。 [[ViewController alloc] init]; [[ViewController alloc]initWithNibName:@"xibName" bundle:nil]; 第二種:代理類加載xib 1 . xib文件裡面需要一個ViewController,並將xib的 File's Owner的Identity inspector中的class設置為應用程序代理類。 2 . 代理類中添加一個ViewController插座變量並連接。 3 . 在application:didFinishLaunchingWithOptions:方法中加載xib文件。 第三種:串聯圖 2.視圖控制器如何創建視圖 UIViewController中有loadView這個方法,默認情況下,自己的視圖控制器並沒有重寫這個方法,本人測試過,當第一次訪問view這個屬性的時候,就會自動調用loadView這個方法,重寫這個方法,代碼如下: - (void)loadView{ self.view = [[UIView alloc] init]; } 跟不重寫一樣的效果,所以本人就猜想UIViewController中loadView這個方法也是如此實現(沒有使用xib的情況下),歡迎指正。 3.view的生命周期 UIViewController中聲明如下方法: 復制代碼 //加載視圖 - (void)loadView; //j將要卸載視圖 - (void)viewWillUnload NS_DEPRECATED_IOS(5_0,6_0); //已經卸載視圖 - (void)viewDidUnload NS_DEPRECATED_IOS(3_0,6_0); //已經加載 - (void)viewDidLoad; //視圖將要顯示 - (void)viewWillAppear:(BOOL)animated; //視圖已經顯示 - (void)viewDidAppear:(BOOL)animated; //視圖將要隱藏 - (void)viewWillDisappear:(BOOL)animated; //視圖已經隱藏 - (void)viewDidDisappear:(BOOL)animated; //將要調用layoutSubviews - (void)viewWillLayoutSubviews NS_AVAILABLE_IOS(5_0); //已經調用layoutSubviews - (void)viewDidLayoutSubviews NS_AVAILABLE_IOS(5_0); 復制代碼 可以重寫這些方法進行生命生命周期的管理。 4.旋轉 視圖控制器的一個主要任務就是知道如何旋轉視圖,有兩種不同旋轉: 抵消旋轉 應用的旋轉是為了抵消設備方向的旋轉,從而應用可以根據用戶如何手持設備而正確的顯示。抵消旋轉的挑戰僅僅在於屏幕不是正方形,這意味著,如果應用旋轉90度,界面不再適合屏幕,必須做出改變進行抵消。 強制旋轉 當某個特定的視圖出現在上界面上時應用進行旋轉,或者在應用啟東時,為了告訴用戶需要旋轉設備才能正確顯示視圖。這是很常見的,因為界面是特地的設計的,而屏幕並不是正方形,所以事實上只能顯示某一特定的模式(豎屏或橫屏)。 為了支持旋轉,視圖控制器需要做的事就是重寫shouldAutorotateToInterfaceOrientation:,傳入的參數是當前設備的方向,是如下之一: UIInterfaceOrientationPortrait Home健在下方 UIInterfaceOrientationPortraitUpsideDown Home健在下方 UIInterfaceOrientationLandscapeLeft Home健在左邊 UIInterfaceOrientationLandscapeRight Home健在右邊 返回YES允許所有方向旋轉,否則返回NO,如果沒有重寫這個方法,默認是對UIInterfaceOrientationPortrait 返回YES,而其他方向返回NO的,必須對某些方向返回YES。(沒有UIViewController屬性可以設置為視圖控制器可旋轉的方向,只能重寫這個方法)。 iOS 5有一個新特性,就是shouldAutorotateToInterfaceOrientation可以動態的實現, 使用attemptRotationToDeviceOrientation這個方法 該方法的使用場景是 interface orientation和device orientation 不一致,但希望通過重新指定 interface orientation 的值,立即實現二者一致;如果這時只是更改了支持的 interface orientation 的值,沒有調用attemptRotationToDeviceOrientation,那麼下次 device orientation 變化的時候才會實現二者一致,關鍵點在於能不能立即實現。 舉個例子: 假設當前的 interface orientation 只支持 Portrait,如果 device orientation 變成 Landscape,那麼 interface orientation 仍然顯示 Portrait; 如果這時我們希望 interface orientation 也變成和 device orientation 一致的 Landscape,以iOS 6 為例,需要先將 supportedInterfaceOrientations 的返回值改成Landscape,然後調用 attemptRotationToDeviceOrientation方法,系統會重新詢問支持的 interface orientation,已達到立即更改當前 interface orientation 的目的。 旋轉事件 可以通過視圖控制器的interfaceOrientation屬性知道當前界面的方向, UIViewController的子類可以重寫下列方法,以便在旋轉的前後收到通知: - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation