三十而立,從零開始學ios開發(十):Multiview Applications(多個xib之前的切換)

來源:互聯網
上載者:User

這篇學習的主要內容是Multiview,在我們學習iphone旋轉的時候,介紹過多個view的使用方法,不過這裡的view和旋轉螢幕中所指的多個view是不同的,旋轉螢幕中涉及到的多個view是在一個xib檔案中的,而我們這裡所指的mulitview,則是指多個xib,在多個xib中進行view的切換,也就是從一個xib切換到另一個xib,而每個xib中只有一個view。

另外的一個不同點體現在建立項目的時候,到目前為止,我們建立的所有項目的template都是single view,這次建立的項目將使用新的template。

Multiview applicatin的基本架構,一般來說,一個multiview application會有一個主要的controller來控制view的呈現,這個主要的controller可以是toolbar(iphone上的Safari開啟後,地下的一排按鈕就是toolbar)或者是tab bar(iphone開啟phone,最下面一個一個的tab),或者其他的一些控制項,他們控制到底那個view應該顯示,那個view應該被隱藏,也就是說,至少需要3個view才能實現view的切換,一個主要的controller view,2個其他的用於切換的view,主要的controller view是一直顯示在螢幕上的,而其他的view中,只有1個會顯示出來,其他的都被隱藏。ok,下面開始一步一步實現multiview吧,再說下去會越來越糊塗的。

0)項目簡介
今天要做的例子中包含3個view,一個controller view,我們會使用toolbar,2個用於切換的view,一個藍色底,一個黃色底,他們中間都有一個button,單擊button會有一個警告框彈出,告訴使用者當前顯示的是哪個view。

1)建立一個工程,選擇Empty Application

這次不再選擇Single View Application,而選擇Empty Application,項目中的所有檔案我們都會手動進行添加。

單擊Next按鈕,之後的操作和建立Single View項目一樣,設定項目名稱“View Switcher”,設定項目儲存路徑,項目建立完成。

2)添加View Controller
由於我們使用的模板是Empty Application,因此當建立完項目後,只有以下一些檔案

裡面並沒有我們需要的controller view,也沒有任何xib檔案,這些都是需要我們手動添加的。使用快速鍵command+N或者功能表列File>New>New File...,在彈出的視窗中,左邊選擇Cocoa Touch,右邊選擇UIViewController subclass,點擊Next按鈕

填寫類名BIDSwitchViewController,其他都是預設選項(注意最後一個checkbox,如果選擇了,則將建立一個和BIDSwitchViewController關聯的xib檔案,我們在這裡可以選上,但是為了弄清楚view controller和xib檔案是如何關聯在一起的,在這個項目中我們暫時不選,後面我們會手動串連這兩個檔案),點擊Next按鈕。

選擇保持的位置,儲存在“View Switcher”目錄下,完成建立。

BIDSwitchViewController是項目的最頂層的view controller(root controller),它用於控制另外2個view的切換,下面按照同樣的方法,建立另外2個view controller,一個名字教BIDBlueViewController,另一個叫做BIDYellowViewController,他們都不需要關聯xib,且都儲存在“View Switcher”目錄下。建立完成後的“View Switcher”結構如下

3)添加xib檔案
使用快速鍵command+N或者功能表列File>New>New File...,在彈出的視窗中,左邊選擇User Interface,右邊選擇View,點擊Next按鈕

Device Family中選擇iphone,點擊Next

命名為SwitchView.xib,同樣保持在“View Switcher”目錄下,點擊Create,完成建立。

使用同樣的方法建立另外兩個xib,分別命名為BlueView.xib和YellowView.xib。至此,我們所有的檔案都已經建立完畢,整個的“View Switcher”結構圖如下

接下來就是寫代碼的工作了。

4)編輯BIDAppDelegate檔案
當一個app啟動的時候,我們都會預設的把一個view載入當前的iphone視窗(application's main window),在這個例子中,這個view就是我們的root view,即BIDSwitchViewController。我們是在BIDAppDelegate檔案中設定預設載入的view的,因此首先開啟BIDAppDelegate.h,添加class BIDSwitchViewController,和它的一個property,如下

#import <UIKit/UIKit.h>@class BIDSwitchViewController;@interface BIDAppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@property (strong, nonatomic) BIDSwitchViewController *switchViewController;@end

其中,@class是告訴BIDAppDelegate,後面的BIDSwitchViewController是一個類,應該以類的方式處理該對象,後面在聲明property的時候,BIDAppDelegate就知道BIDSwitchViewController是一個類,不會不認該對象。

接著開啟BIDAppDelegate.m,添加如下代碼

#import "BIDAppDelegate.h"#import "BIDSwitchViewController.h"@implementation BIDAppDelegate@synthesize window = _window;@synthesize switchViewController;- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];    // Override point for customization after application launch.        self.switchViewController = [[BIDSwitchViewController alloc] initWithNibName:@"SwitchView" bundle:nil];    UIView *switchView = self.switchViewController.view;    CGRect switchViewFrame = switchView.frame;    switchViewFrame.origin.y += [UIApplication sharedApplication].statusBarFrame.size.height;    switchView.frame = switchViewFrame;    [self.window addSubview:switchView];        self.window.backgroundColor = [UIColor whiteColor];    [self.window makeKeyAndVisible];    return YES;}......

首先import BIDSwitchViewController,然後聲明synthesize,對應於標頭檔中的property。

didFinishLaunchingWithOption方法,當一個app載入完成後需要做一些什麼事情,在這裡,我們指定了哪個view被載入到windows中作為預設顯示的view。

self.switchViewController = [[BIDSwitchViewControlleralloc] initWithNibName:@"SwitchView" bundle:nil];
通過xib(在舊的版本中,xib被稱為nib,因此這裡出現的是NibName)的名字來制定初始化哪個view

UIView *switchView = self.switchViewController.view;
擷取view

CGRect switchViewFrame = switchView.frame;
得到view的frame,也就是這個view的顯示位置,在前幾篇的文章中提到過這個屬性。

switchViewFrame.origin.y += [UIApplicationsharedApplication].statusBarFrame.size.height;
我覺得這句話比較重要,它將view的位置往下移動了20point(point在非retina螢幕中是20px,在retina螢幕中是40px),這樣就不會擋住iphone頂部的狀態列了。

switchView.frame = switchViewFrame;
將修改過的frame從新賦值給switchView

[self.window addSubview:switchView];
將switchView設定成window的subview。怎麼理解這句話呢,就是說,一個app只有一個視窗(window),這個window只能同時顯示一個view,且這個view是基於這個window而存在的,是放在這個window裡面的,因此稱之為window的subview,子視圖。

5)編輯BIDSwitchViewController.h
BIDSwitchViewController是root controller,用於控制其他2個view的切換,因此需要在其標頭檔中聲明其他兩個controller,然後需要定義一個Action,用來完成對2個view的切換,將BIDSwitchViewController.h修改成如下

#import <UIKit/UIKit.h>@class BIDBlueViewController;@class BIDYellowViewController;@interface BIDSwitchViewController : UIViewController@property (strong, nonatomic) BIDBlueViewController *blueViewController;@property (strong, nonatomic) BIDYellowViewController *yellowViewController;- (IBAction)switchViews:(id)sender;@end

代碼還是很好理解的,和前面在BIDAppDelegate.h中添加BIDSwitchViewController是一樣的。

6)關聯BIDSwitchViewController和SwitchView.xib
在Project Navigator中選中SwitchView.xib,在xib的dock中選中File's Owner

然後在Identity inspector中將Class改成BIDSwitchViewController

這樣就將SwitchView.xib關聯到了BIDSwitchViewController,如果我們選擇Connections inspector,會看到我們剛才在BIDSwitchViewController.h中定義的Action:switchViews出現在Received Actions,我們之後就可以將這個Action關聯到SwitchView.xib的控制項上。

7)在SwitchView.xib上添加Toolbar
在這個例子總,我們切換veiw的方式是點擊Toolbar上的一個button,然後切換2個view,SwitchView.xib使我們的root view,因此我們需要在SwitchView.xib上添加一個toolbar,然後點擊toolbar上的按鈕,切換BlueView.xib和YellowView.xib。

選中SwitchView.xib,在object library中找到Toolbar

拖動到View上,放在最下方

預設的,已經有一個button在Toolbar上了,雙擊button改變文字,將文字改成“Switch Views”

接著就是將“Switch Views”按鈕關聯到switchViews,選中“Switch Views”,control-dragged到File's Owner,在彈出的框中選中switchViews

開啟Connections inspector,我們可以看到關聯後的情況

有一個不同的地方,Toolbar上的button不像一般的button,會有很多的方法讓你進行關聯,Toolbar上button的Sent Actions(其他的button叫做Send Events,有很多個方法)只有一個方法,而它的作用相當於一般button的touch up inside。

8)關聯SwitchView.xib和BIDSwitchViewController's view outlet
BIDSwitchViewController繼承自UIViewController,在UIViewController中有一個outlet view,另外當我們在做第6)步的時候,將SwitchView.xib的class改成了BIDSwitchViewController,所以我們要將這個view關聯到SwitchView.xib,關聯的方法是選中SwitchView.xib,然後選中File's Owner,control-drag到下面的View

釋放滑鼠後,在填出的框中選則view,這樣就關聯好了。

關聯好後,查看Connections inspector,也可以看到關聯後的結果

9)編輯BIDSwitchViewController.m
添加如下代碼

#import "BIDSwitchViewController.h"#import "BIDYellowViewController.h"#import "BIDBlueViewController.h"@implementation BIDSwitchViewController@synthesize yellowViewController;@synthesize blueViewController;

2個#import這個很好理解,因為BIDSwitchViewController是root controller,會控制另外2個controller,因此需要把另外2個controller引入進來,這樣才可以對他們進行操作。
2個synthesize對著標頭檔中的2個property。

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.- (void)viewDidLoad{    self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];    [self.view insertSubview:self.blueViewController.view atIndex:0];    [super viewDidLoad];}

首先去掉viewDidLoad的注釋,然後添加以上的代碼。從最後一句可以看出,viewDidLoad方法繼承自UIViewController,在這裡對其重載,這個方法發生在當view已經載入完成後,我們所要做的是當root view載入完成後,在載入root view的subview,在我們的這個例子中是BlueView。BlueView的載入方法和前面的一樣,使用initWithNibName,然後作為subView插入到當前的view中(當前的view就是root view,也就是SwitchView)。

- (IBAction)switchViews:(id)sender{    if(self.yellowViewController.view.superview == nil) {        if(self.yellowViewController == nil) {            self.yellowViewController = [[BIDYellowViewController alloc] initWithNibName:@"YellowView" bundle:nil];        }        [blueViewController.view removeFromSuperview];        [self.view insertSubview:self.yellowViewController.view atIndex:0];    } else {        if (self.blueViewController ==nil) {            self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];        }        [yellowViewController.view removeFromSuperview];        [self.view insertSubview:self.blueViewController.view atIndex:0];    }}

實現switchViews Action,上面的代碼還是很好理解的,首先判斷當前哪個subview是沒有superview的,因為這2個subview不會同時顯示,當blueSubview顯示時,YellowSubview就會從root view中移除,因此不會具有superview,當得知那個subview沒有superview,就說明應該顯示這個subview。知道該顯示哪個subview後,再判斷這個subview是否還存在(是否需要重新載入初始化),然後將另一個subview從superview中移除,再將subview顯示出來。

- (void)didReceiveMemoryWarning{    // Releases the view if it doesn't have a superview.    [super didReceiveMemoryWarning];        // Release any cached data, images, etc that aren't in use.    if (self.blueViewController.view.superview == nil){        self.blueViewController = nil;    } else {        self.yellowViewController = nil;    }}

當ios的記憶體不夠用時,didReceiveMemoryWarning會被系統自動調用,來釋放可利用的記憶體。在這裡如果哪個subview沒有顯示,就釋放該subview,騰出記憶體。

至此BIDSwitchViewController的所有代碼都寫好了,下面就應該處理BIDBlueVeiwController和BIDYellowViewController了。

(友情提示,時不時的編譯一下你的project,儘早發現問題,容易修改,否則到後面自己都不知道錯在哪裡)

10)編輯BlueView.xib和YellowView.xib
分別在BlueView.xib和YellowView.xib上添加一個button,並命名為“Press me”。

修改BlueView.xib的class為BIDBlueViewController,修改YellowView.xib的class為BIDYellowController(修改方法:選中xib,點擊File's Owner,在Identity inspector中更改class)
 
class改變了,就需要重新關聯一下File's owner的view,方法和之前的一樣,選中File‘s Owner,control-drag到下面的View上,在彈出的框中選擇view,關聯完畢,2個xib都需要進行這個操作。

在Attributes inspector中,將BlueView.xib的background顏色改成藍色

同樣的方法將YellowView.xib的background顏色改成黃色

還有一個地方需要設定,因為我們是在root view中顯示這2個subview,而root view有一個toolbar在最下方,因此subview需要把toolbar的位置空出來,再進行自己的布局,還是開啟Attributes inspector,在Simulated Metrics欄中有很多現象,他們都是用來類比iphone螢幕上各種佔位控制項的,我們將Button Bar的選項設成Toolbar,這樣xib就會空出Toolbar的位置來進行布局計算了

仔細看的話,“Press me”按鈕的位置往上移動了那麼一點點

11)在BIDBlueViewController和BIDYellowViewController中添加代碼
在BIDBlueViewController.h中添加Action,如下

@interface BIDBlueViewController : UIViewController- (IBAction)blueButtonPressed;@end

在BIDBlueViewController.m中實現blueButtonPressed,如下

- (IBAction)blueButtonPressed{    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Blue View Button Pressed"                                                    message:@"You pressed the button on the blue view"                                                   delegate:nil                                          cancelButtonTitle:@"Yep, I did"                                          otherButtonTitles:nil];    [alert show];}

在BIDYellowViewController.h添加Action,如下

@interface BIDYellowViewController : UIViewController- (IBAction)yellowButtonPressed;@end

在BIDYellowViewController.m中實現yellowButtonPressed,如下

- (IBAction)yellowButtonPressed{    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Yellow View Button Pressed"                                                    message:@"You pressed the button on the yellow view"                                                   delegate:nil                                          cancelButtonTitle:@"Yep, I did"                                          otherButtonTitles:nil];    [alert show];}

代碼都很簡單,就不多做解釋了。

12)關聯button和Action
開啟BlueView.xib,選中“Press me”按鈕,control-drag到File's owner釋放,在填出的框中選擇blueButtonPressed。
開啟YellowView.xib,選中“Press me”按鈕,control-drag到File's owner釋放,在填出的框中選擇yellowButtonPressed。

13)編譯運行
至此我們已經可以編譯運行程式了,編譯成功後,iphone模擬器中顯示的效果(“Press me”按鈕的效果就不示範了)

按下“Switch Views”按鈕,BlueSubview會切換到YellowSubview

14)更炫的切換view的方法
有沒有發現上面切換view效果很無聊,ios中有更炫的切換view的方法,使用動畫的方式切換view,開啟BIDSwitchViewController.m,重新編輯switchViews方法,如下

- (IBAction)switchViews:(id)sender{        [UIView beginAnimations:@"View Flip" context:nil];    [UIView setAnimationDuration:1.25];    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];        if(self.yellowViewController.view.superview == nil) {        if(self.yellowViewController == nil) {            self.yellowViewController = [[BIDYellowViewController alloc] initWithNibName:@"YellowView" bundle:nil];        }        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];        [blueViewController.view removeFromSuperview];        [self.view insertSubview:self.yellowViewController.view atIndex:0];    } else {        if (self.blueViewController ==nil) {            self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];        }        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];        [yellowViewController.view removeFromSuperview];        [self.view insertSubview:self.blueViewController.view atIndex:0];    }    [UIView commitAnimations];}

[UIViewbeginAnimations:@"View Flip" context:nil];
先可以不用理解這句話的意思,因為我也沒有理解,反正這行代碼是聲明一個animation block,前一個參數是設定animation block的title,後一個參數是設定一個對象,我也搞不清楚是幹什麼的,大概在以後的學習中會有所瞭解。

[UIViewsetAnimationDuration:1.25];
設定動畫時間,即切換view的時間

[UIViewsetAnimationCurve:UIViewAnimationCurveEaseInOut];
設定動畫的運動方式,開始慢,中間快,最後慢,大家開始看ios自己的說明吧。(An ease-in ease-out curve causes the animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing. This is the default curve for most animations.)

[UIViewsetAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
設定切換的樣式,一共有4個值可以選:
UIViewAnimationTransitionFlipFromRight
UIViewAnimationTransitionFlipFromLeft
UIViewAnimationTransitionFlipCurUp
UIViewAnimationTransitionFlipCurDown
這個大家自試試就可以知道了

[UIViewcommitAnimations];
當所有動畫的值設定完畢後,提交動畫,之後view就會按照設定的動畫進行view的切換了。

(此圖截於書本,因此不同清晰)

15)總結
ok,所有的功能都已經完成了,在這個例子中,我們使用toolbar來完成對不同view的切換,我們需要一個root view進行總的控制,然後多個subview進行切換,最後還使用一個比較炫的效果進行view之間的轉換,內容很充實!

View Switcher

 

 

 

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.