自訂視圖控制器切換(iOS)

來源:互聯網
上載者:User

標籤:style   blog   class   code   java   c   

在iOS開發過程中,通常我們會使用UINavigationController,UITabbarController等蘋果提供的視圖控制器來切換我們的視圖。在iOS5之前,如果要自訂[內容] 檢視控制器很麻煩,比如你要考慮到子視圖的生命週期,當裝置旋轉時的情況等,好在iOS5中蘋果提供了添加視圖控制器(addChildViewController)等管理檢視控制器的API,這樣我們就能使用此API來自訂自己的視圖控制器了,這篇文章只要介紹如何使用此API實現UITabbarController的準系統。

開始

使用過UITabbarController的都知道,UITabbarController可以在多個UIViewController中切換,來顯示多個介面,先來看一下層級關係:

TabbarController作為根視圖,然後添加了一個ChildViewController,最後使用者看到內容是ChildViewController的視圖內容和底部的TabBar

首先我們建立一個新的工程,選擇Single View Application,啟用StoryBoard,將其預設的ViewController作為ContainerViewController,然後建立兩個新的ViewController,分別作為兩個childViewController,這樣目錄中就有這些檔案:

我們先進入StoryBoard拖入兩個UIButton,給兩個button設定tag:

然後建立兩個ViewController,這裡我啟用了xib,設定一下ViewController的背景色:

這裡我一個設定了綠色,還有個設定了棕色,還分別在每個ViewController上添加了UILabel,用於區分

然後進入ContainerViewController.m,聲明以下私人變數和方法:

@interface ContainerViewController () {    FirstViewController *_firstViewController;    SecondViewController *_secondViewController;        NSMutableArray *_viewControllers;}

- (IBAction)buttonTouched:(id)sender;


FirstViewController和SecondViewController是兩個ChildViewController,_viewControllers則是儲存ChildViewController的數組,再去StoryBoard關聯下點擊事件

在viewDidLoad中初始化:

- (void)viewDidLoad{    [super viewDidLoad];        _viewControllers = [@[] mutableCopy];    _firstViewController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];    _secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];        [_viewControllers addObject:_firstViewController];    [_viewControllers addObject:_secondViewController];        [self loadViewControllerAtIndex:0];}

執行個體化了兩個ViewController,然後將兩個ViewController添加至數組中

關鍵區段來了,loadViewControllerAtIndex用於切換視圖控制器,以下是實現:

- (void)loadViewControllerAtIndex:(NSInteger)index {    NSInteger nextIndex = 0;    if (index == 0) {        nextIndex = 1;    } else if (index == 1) {        nextIndex = 0;    }        UIViewController *fromViewController = _viewControllers[nextIndex];// 擷取當前viewController    UIViewController *toViewController = _viewControllers[index];// 擷取將要切換的viewController    
  // if (self.childViewControllers.firstObject == toViewController) { return; } if (self.childViewControllers.count > 0) { self.view.userInteractionEnabled = NO;// 切換過程中禁用操作,等切換動畫結束後恢複 [fromViewController willMoveToParentViewController:nil];// fromViewController將要移除 [self addChildViewController:toViewController];// 將toViewController添加至ContainerViewController
     // 設定view的frame if (index == 1) { toViewController.view.frame = [self nextViewStartFrame]; } else { toViewController.view.frame = [self preViewStartFrame]; }
     // 官方提供的切換動畫API,在這裡執行切換動畫 [self transitionFromViewController:fromViewController toViewController:toViewController duration:0.25 options:UIViewAnimationOptionCurveEaseInOut animations:^{
         // 執行動畫 if (index == 1) { fromViewController.view.frame = [self preViewStartFrame]; toViewController.view.frame = [self newViewStartFrame]; } else { fromViewController.view.frame = [self nextViewStartFrame]; toViewController.view.frame = [self newViewStartFrame]; } } completion:^(BOOL finished) {
       // 動畫執行完畢,從父視圖添加或移除層級關係 if (finished) { [toViewController didMoveToParentViewController:self]; [fromViewController removeFromParentViewController]; self.view.userInteractionEnabled = YES; } }]; } else { [self addChildViewController:toViewController]; [self.view addSubview:toViewController.view]; [toViewController didMoveToParentViewController:self]; }}

- (CGRect)newViewStartFrame {

    returnCGRectMake(0.0, 0.0, 320.0, 500.0);

}


- (CGRect)nextViewStartFrame {

    returnCGRectMake(320.0, 0.0, 320.0, 500.0);

}


 - (CGRect)preViewStartFrame {

    returnCGRectMake(-320.0, 0.0, 320.0, 500.0);

}


這個函數用於切換視圖,使用addChildViewController把要添加的ViewController添加至ContainerViewController,移除不需要顯示的。添加一個ViewController有幾個步驟:

1. [self addChildViewController:toViewController];  添加至當前viewController

2. [self.view addSubView:toViewController.view];   添加view至self.view中

3. [toViewController didMoveToParentViewController:self];  當添加完成後要調用此方法來告知已經移動到父視圖控制器中

移除一個ViewController也有幾個步驟:

1. [fromViewController willMoveToParentViewController:nil];  參數傳入nil說明將要移除視圖

2. [fromViewController.view removeFromSuperView];  從父視圖中移除fromViewController.view

3. [fromViewController removeFromParentViewController];  將fromViewController從父視圖層級中移除

想要添加和移除ViewController這幾個步驟是必要的,但是這裡由於使用了transitionFromViewController:toViewController:duration:options:animations:completion:這個方法,它會先將toViewController.view添加至superView,然後執行動畫,所以省略了[self.view addSubView:toViewController.view]

這樣切換函數就算完成了,然後我們實現按鈕事件函數:

- (IBAction)buttonTouched:(id)sender {    if (((UIButton *)sender).tag == 1) {                [self loadViewControllerAtIndex:0];    } else {        [self loadViewControllerAtIndex:1];    }}

點擊不同的按鈕切換不同的介面,最後運行效果如下:

這裡只是大致實現了下轉場效果,在iOS7中新增的UIViewControllerContextTransitioning和UIViewControllerAnimatedTransitioning增強了對自訂的切換,這篇文章做了詳細說明http://objccn.io/issue-12-3/

 

參考:https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html#//apple_ref/doc/uid/TP40007457-CH18-SW6

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.