在iOS开发中视图的切换是很频繁的,独立的视图应用在实际开发过程当中并不常见,除非你的应用足够简单。在iOS开发中经常使用的视图切换有三种,今天咱们将一一介绍:html
iOS三种视图切换的原理各不相同:web
UITabBarController 是Apple专门为了利用页签切换视图而设计的,在这个视图控制器中有一个UITabBar控件,用户经过点击tabBar进行视图切换。咱们知道在 UIViewController内部有一个视图,一旦建立了UIViewController以后默认就会显示这个视图,可是 UITabBarController自己并不会显示任何视图,若是要显示视图则必须设置其viewControllers属性(它默认显示 viewControllers[0])。这个属性是一个数组,它维护了全部UITabBarController的子视图。为了尽量减小视图之间的耦 合,全部的UITabBarController的子视图的相关标题、图标等信息均由子视图本身控制,UITabBarController仅仅做为一个 容器存在。数据库
假设如今有一个KCTabBarViewController(继承于UITabBarController),它内部有一个KCWebChatViewController、一个KCContactViewController。数组
1.首先建立一个KCTabBarViewController继承于UITabBarController(代码是默认生成的,再也不贴出来)。微信
2.其次建立两个子视图,在这两个子视图控制器中设置对应的名称、图标等信息。app
KCWebChatViewController.mide
//
// KCWorldClockViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCWebChatViewController.h" @interface KCWebChatViewController () @end @implementation KCWebChatViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor=[UIColor redColor]; //设置视图控制器标题 self.title=@"Chat"; //注意经过tabBarController或者parentViewController能够获得其俯视图控制器(也就是KCTabBarViewController) NSLog(@"%i",self.tabBarController==self.parentViewController);//对于当前应用两者相等 //设置图标、标题(tabBarItem是显示在tabBar上的标签) self.tabBarItem.title=@"Web Chat";//注意若是这个标题不设置默认在页签上显示视图控制器标题 self.tabBarItem.image=[UIImage imageNamed:@"tabbar_mainframe.png"];//默认图片 self.tabBarItem.selectedImage=[UIImage imageNamed:@"tabbar_mainframeHL.png"];//选中图片 //图标右上角内容 self.tabBarItem.badgeValue=@"5"; } @end
KCContactViewController.m学习
//
// KCAlarmViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCContactViewController.h" @interface KCContactViewController () @end @implementation KCContactViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor=[UIColor yellowColor]; self.tabBarItem.title=@"Contact"; self.tabBarItem.image=[UIImage imageNamed:@"tabbar_contacts.png"]; self.tabBarItem.selectedImage=[UIImage imageNamed:@"tabbar_contactsHL.png"]; } @end
3.在应用程序启动后设置Tab bar视图控制器的子视图,同时将Tab bar视图控制器做为window的根控制器。ui
AppDelegate.mthis
//
// AppDelegate.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "AppDelegate.h" #import "KCTabBarViewController.h" #import "KCWebChatViewController.h" #import "KCContactViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { _window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds]; KCTabBarViewController *tabBarController=[[KCTabBarViewController alloc]init]; KCWebChatViewController *webChatController=[[KCWebChatViewController alloc]init]; KCContactViewController *contactController=[[KCContactViewController alloc]init]; tabBarController.viewControllers=@[webChatController,contactController]; //注意默认状况下UITabBarController在加载子视图时是懒加载的,因此这里调用一次contactController,不然在第一次展现时只有第一个控制器tab图标,contactController的tab图标不会显示 for (UIViewController *controller in tabBarController.viewControllers) { UIViewController *view= controller.view; } _window.rootViewController=tabBarController; [_window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } @end
运行效果:
对于UITabBarController简单总结以下:
注意:使用storyboard建立UITabBarController的内容今天再也不着重讲解,内容比较简单,你们能够本身试验。
UINavigationController是一个导航控制器,它用来组织有层次关系的视图,在UINavigationController中 子控制器以栈的形式存储,只有在栈顶的控制器可以显示在界面中,一旦一个子控制器出栈则会被销毁。UINavigationController默认也不 会显示任何视图(这个控制器自身的UIView不会显示),它必须有一个根控制器rootViewController,并且这个根控制器不会像其余子控 制器同样被销毁。
下面简单经过几个视图模拟一下微信添加好友的功能,假设有一个导航控制器,它的根控制器为好友列表控制器 KCFriendViewController,经过它能够导航到添加QQ联系人视图KCQQContactViewController,在QQ联系人 视图又能够导航到公共帐号视图KCPublicAccountViewController。
1.首先在应用代理启动后初始化一个导航控制器并设置其根控制器为KCFriendViewController
//
// AppDelegate.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "AppDelegate.h" #import "KCTabBarViewController.h" #import "KCWebChatViewController.h" #import "KCContactViewController.h" #import "KCFriendViewController.h" #import "KCQQContactViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { _window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds]; _window.backgroundColor =[UIColor colorWithRed:249/255.0 green:249/255.0 blue:249/255.0 alpha:1]; //设置全局导航条风格和颜色 [[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:23/255.0 green:180/255.0 blue:237/255.0 alpha:1]]; [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]; KCFriendViewController *friendController=[[KCFriendViewController alloc]init]; UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:friendController]; _window.rootViewController=navigationController; [_window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } @end
2.在好友列表视图控制器中设置导航栏左右按钮,而且设置点击右侧按钮导航到添加QQ联系人视图
//
// KCFriendViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCFriendViewController.h" #import "KCQQContactViewController.h" @interface KCFriendViewController () @end @implementation KCFriendViewController - (void)viewDidLoad { [super viewDidLoad]; //每次出栈都会销毁相应的子控制器 NSLog(@"childViewControllers:%@",self.navigationController.childViewControllers); //在子视图中能够经过navigationController属性访问导航控制器, //同时对于当前子视图来讲其父控制器就是其导航控制器 NSLog(@"%i",self.navigationController==self.parentViewController); //在子视图中(或者根视图)有一个navigationItem用于访问其导航信息 self.navigationItem.title=@"Friends";//或者直接设置控制器title(例如[self setTitle:@"Friends"]) //设置导航栏左侧按钮 self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"Edit" style:UIBarButtonSystemItemAdd target:nil action:nil]; //设置导航栏右侧按钮 self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"ff_IconAdd.png"] style:UIBarButtonItemStyleDone target:self action:@selector(addFriends)]; } -(void)addFriends{ //经过push导航到另一个子视图 KCQQContactViewController *qqContactController=[[KCQQContactViewController alloc]init]; [self.navigationController pushViewController:qqContactController animated:YES]; } @end
3.在QQ联系人视图右侧导航中添加一个导航到公共帐号的按钮
//
// KCQQContactViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCQQContactViewController.h" #import "KCPublicAccountViewController.h" @interface KCQQContactViewController () @end @implementation KCQQContactViewController - (void)viewDidLoad { [super viewDidLoad]; //每次出栈都会销毁相应的子控制器 NSLog(@"childViewControllers:%@",self.navigationController.childViewControllers); [self setTitle:@"QQ Contact"]; //self.title=@"QQ contact"; //self.navigationItem.title=@"My QQ"; UIBarButtonItem *back=[[UIBarButtonItem alloc]initWithTitle:@"QQ" style:UIBarButtonItemStyleDone target:nil action:nil]; self.navigationItem.backBarButtonItem=back; self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"Public Account" style:UIBarButtonItemStyleDone target:self action:@selector(gotoNextView)]; } -(void)gotoNextView{ KCPublicAccountViewController *publicAccountController=[[KCPublicAccountViewController alloc]init]; [self.navigationController pushViewController:publicAccountController animated:YES]; } @end
4.在公共帐号视图中在导航栏右侧设置一个按钮用于直接返回根视图
//
// KCPublicNumberViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCPublicAccountViewController.h" @interface KCPublicAccountViewController () @end @implementation KCPublicAccountViewController - (void)viewDidLoad { [super viewDidLoad]; //每次出栈都会销毁相应的子控制器 NSLog(@"childViewControllers:%@",self.navigationController.childViewControllers); self.title=@"Public Account"; self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"Add Friends" style:UIBarButtonItemStyleDone target:self action:@selector(gotoAddFriends)]; } -(void)gotoAddFriends{ //直接跳转到根控制器,也可使用- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated; 方法 [self.navigationController popToRootViewControllerAnimated:YES]; } @end
演示效果:
鉴于不少初学者在学习UINavigationController时看到的多数是使用storyboard方式建立导航,并且storyboard中的segue不少初学者不是很了解,这里简单对storyboard方式建立导航进行介绍。
下面简单作一个相似于iOS系统设置的导航程序,系统默认进入Settings视图控制器,在Settings界面点击General进行General视图,点击Sounds进入Sounds视图,就那么简单。
1.首先在Main.storyboard中拖拽一个UINavigationController将应用启动箭头拖拽到新建的 UINavigationController中将其做为默认启动视图,在拖拽过程当中会发现UINavigationController默认会带一个 UITableViewController做为其根控制器。
2.设置UITableViewController的标题为“Settings”,同时设置UITableView为静态表格而且包含两行,分别在两个UITableViewCell中放置一个UILabel命名为”General”和“Sounds”。
3.新建两个UITableViewController,标题分别设置为“General”、“Sounds”,按住Ctrl拖拽 “Settings”的第一个UITableViewCell到视图控制器“General”,同时选择segue为“push”,拖拽第二个 UITableViewCell到视图控制器“Sounds”,同时选择segue为“push”。
到这里其实咱们已经能够经过Settings视图导航到General和Sounds视图了,可是storyboard是如何处理导航的呢?
前面咱们看到导航的过程是经过一个名为“Segue”链接建立的(前面采用的是push方式),那么这个Segue是如何工做的呢?Segue的工做方式分为如下几个步骤:
1.建立目标视图控制器(也就是前面的General、Sounds视图控制器)
2.建立Segue对象
3.调用源视图对象的prepareForSegue:sender:方法
4.调用Segue对象的perform方法将目标视图控制器推送到屏幕
5.释放Segue对象
要解释上面的过程首先咱们定义一个KCSettingsTableViewController控制器,它继承于 UITableViewController,而后在storyboard中设置“Settings”视图控制器的class属性为 KCSettingsTableViewController。同时设置导航到“General”视图控制器的segue的Identifier为 “GeneralSegue”,设置导航到“Sounds”控制器的segue的Identifier为“SoundsSegue”。
而后修改KCSettingsTableViewController.m添加以下代码:
#pragma mark - 导航 -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ //源视图控制器 UITableViewController *settingController=segue.sourceViewController; //目标视图控制器 UITableViewController *tableViewController=segue.destinationViewController; NSLog(@"sourceController:%@,destinationController:%@",settingController.navigationItem.title,tableViewController.navigationItem.title); }
此时运行程序导航咱们会发现此方法会被调用的同时能够打印源视图控制器和目标视图控制器的信息,这一步对应上面所说的第三个步骤。
接着在”Settings”视图控制器的导航栏左右两侧分别放一个UIBarButtonItem并添加对应事件代码以下:
- (IBAction)toGeneral:(id)sender {
[self performSegueWithIdentifier:@"GeneralSegue" sender:self]; } - (IBAction)toSounds:(id)sender { [self performSegueWithIdentifier:@"SoundsSegue" sender:self]; }
此时运行程序发现,使用两个按钮一样能够导航到对应的视图控制器,这一步对应上面第四个步骤,只是默认状况下是本身执行的,这里咱们经过手动调用来演示了这个过程。
运行效果以下:
模态窗口只是视图控制器显示的一种方式(在iOS中并无专门的模态窗口类),模态窗口不依赖于控制器容器(例如前两种视图切换一个依赖于 UITabBarController,另外一个依赖于UINavigationController),一般用于显示独立的内容,在模态窗口显示的时其余 视图的内容没法进行操做。
模态窗口使用起来比较容易,通常的视图控制器只要调用- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0);方法那么参数中的视图控制器就会以模态窗口的形式展示,同时调用- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);方法就会关闭模态窗口。
下面的示例中演示了一个登陆操做,点击主界面左上方登陆按钮以模态窗口的形式展示登陆界面,用户点击登陆界面中的登陆按钮就会返回到主界面。特别强 调一点在下面的示例中导航栏是手动建立的,而不是采用UINavigationController,为了帮助你们熟悉导航栏使用同时也了解了 UInavigationController中导航栏的本质。
1.首先建立一个登陆界面,在界面中只有两个输入框和一个登陆按钮
//
// KCLoginViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCLoginViewController.h" @interface KCLoginViewController () @end @implementation KCLoginViewController - (void)viewDidLoad { [super viewDidLoad]; [self addLoginForm]; } -(void)addLoginForm{ //用户名 UILabel *lbUserName=[[UILabel alloc]initWithFrame:CGRectMake(50, 150, 100, 30)]; lbUserName.text=@"用户名:"; [self.view addSubview:lbUserName]; UITextField *txtUserName=[[UITextField alloc]initWithFrame:CGRectMake(120, 150, 150, 30)]; txtUserName.borderStyle=UITextBorderStyleRoundedRect; [self.view addSubview:txtUserName]; //密码 UILabel *lbPassword=[[UILabel alloc]initWithFrame:CGRectMake(50, 200, 100, 30)]; lbPassword.text=@"密码:"; [self.view addSubview:lbPassword]; UITextField *txtPassword=[[UITextField alloc]initWithFrame:CGRectMake(120, 200, 150, 30)]; txtPassword.secureTextEntry=YES; txtPassword.borderStyle=UITextBorderStyleRoundedRect; [self.view addSubview:txtPassword]; //登陆按钮 UIButton *btnLogin=[UIButton buttonWithType:UIButtonTypeSystem]; btnLogin.frame=CGRectMake(120, 270, 80, 30); [btnLogin setTitle:@"登陆" forState:UIControlStateNormal]; [self.view addSubview:btnLogin]; [btnLogin addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside]; } #pragma mark 登陆操做 -(void)login{ [self dismissViewControllerAnimated:YES completion:nil]; } @end
2.定义主界面视图控制器KCMainViewController,在左上角放一个登陆按钮用于弹出登陆界面
//
// KCMainViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCMainViewController.h" #import "KCLoginViewController.h" @interface KCMainViewController () @end @implementation KCMainViewController - (void)viewDidLoad { [super viewDidLoad]; [self addNavigationBar]; } #pragma mark 添加导航栏 -(void)addNavigationBar{ //建立一个导航栏 UINavigationBar *navigationBar=[[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, 320, 44+20)]; //navigationBar.tintColor=[UIColor whiteColor]; [self.view addSubview:navigationBar]; //建立导航控件内容 UINavigationItem *navigationItem=[[UINavigationItem alloc]initWithTitle:@"Web Chat"]; //左侧添加登陆按钮 UIBarButtonItem *loginButton=[[UIBarButtonItem alloc]initWithTitle:@"登陆" style:UIBarButtonItemStyleDone target:self action:@selector(login)]; navigationItem.leftBarButtonItem=loginButton; //添加内容到导航栏 [navigationBar pushNavigationItem:navigationItem animated:NO]; } #pragma mark 登陆操做 -(void)login{ KCLoginViewController *loginController=[[KCLoginViewController alloc]init]; //调用此方法显示模态窗口 [self presentViewController:loginController animated:YES completion:nil]; } @end
假设用户名输入“kenshincui”,密码输入“123”就认为登陆成功,不然登陆失败。同时登陆成功以后在主视图控制器中显示用户名而且登陆按钮变成“注销”。要实现这个功能主要的问题就是如何把登陆后的用户名信息传递到主界面?由此引出一个问题:多视图参数传递。
在iOS开发中经常使用的参数传递有如下几种方法:
今天咱们主要采用第一种方式进行数据传递,这在iOS开发中也是最多见的一种多视图传参方式。使用代理方式传递参数的步骤以下:
1.定义协议,协议中定义好传参时所须要的方法
2.目标视图控制器定义一个代理对象
3.源视图控制器实现协议并在初始化目标控制器时指定目标控制器的代理为其自身
4.须要传参的时候在目标窗口调用代理的协议方法
具体代码以下:
KCMainViewController.h
//
// KCMainViewController.h
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import <UIKit/UIKit.h> #pragma mark 定义一个协议用于参数传递 @protocol KCMainDelegate -(void)showUserInfoWithUserName:(NSString *)userName; @end @interface KCMainViewController : UIViewController @end
KCMainViewController.m
//
// KCMainViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCMainViewController.h" #import "KCLoginViewController.h" @interface KCMainViewController ()<KCMainDelegate,UIActionSheetDelegate>{ UILabel *_loginInfo; UIBarButtonItem *_loginButton; BOOL _isLogon; } @end @implementation KCMainViewController - (void)viewDidLoad { [super viewDidLoad]; [self addNavigationBar]; [self addLoginInfo]; } #pragma mark 添加信息显示 -(void)addLoginInfo{ _loginInfo =[[UILabel alloc]initWithFrame:CGRectMake(0, 100,320 ,30)]; _loginInfo.textAlignment=NSTextAlignmentCenter; [self.view addSubview:_loginInfo]; } #pragma mark 添加导航栏 -(void)addNavigationBar{ //建立一个导航栏 UINavigationBar *navigationBar=[[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, 320, 44+20)]; //navigationBar.tintColor=[UIColor whiteColor]; [self.view addSubview:navigationBar]; //建立导航控件内容 UINavigationItem *navigationItem=[[UINavigationItem alloc]initWithTitle:@"Web Chat"]; //左侧添加登陆按钮 _loginButton=[[UIBarButtonItem alloc]initWithTitle:@"登陆" style:UIBarButtonItemStyleDone target:self action:@selector(login)]; navigationItem.leftBarButtonItem=_loginButton; //添加内容到导航栏 [navigationBar pushNavigationItem:navigationItem animated:NO]; } #pragma mark 登陆操做 -(void)login{ if (!_isLogon) { KCLoginViewController *loginController=[[KCLoginViewController alloc]init]; loginController.delegate=self;//设置代理 //调用此方法显示模态窗口 [self presentViewController:loginController animated:YES completion:nil]; }else{ //若是登陆以后则处理注销的状况 //注意当前视图控制器必须实现UIActionSheet代理才能进行操做 UIActionSheet *actionSheet=[[UIActionSheet alloc]initWithTitle:@"系统信息" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"注销" otherButtonTitles: nil]; [actionSheet showInView:self.view]; } } #pragma mark 实现代理方法 -(void)showUserInfoWithUserName:(NSString *)userName{ _isLogon=YES; //显示登陆用户的信息 _loginInfo.text=[NSString stringWithFormat:@"Hello,%@!",userName]; //登陆按钮内容改成“注销” _loginButton.title=@"注销"; } #pragma mark 实现注销方法 -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ if (buttonIndex==0) {//注销按钮 _isLogon=NO; _loginButton.title=@"登陆"; _loginInfo.text=@""; } } @end
KCLoginViewController.h
//
// KCLoginViewController.h
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import <UIKit/UIKit.h> @protocol KCMainDelegate; @interface KCLoginViewController : UIViewController #pragma mark 定义代理 @property (nonatomic,strong) id<KCMainDelegate> delegate; @end
KCLoginViewController.m
//
// KCLoginViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCLoginViewController.h" #import "KCMainViewController.h" @interface KCLoginViewController (){ UITextField *_txtUserName; UITextField *_txtPassword; } @end @implementation KCLoginViewController - (void)viewDidLoad { [super viewDidLoad]; [self addLoginForm]; } -(void)addLoginForm{ //用户名 UILabel *lbUserName=[[UILabel alloc]initWithFrame:CGRectMake(50, 150, 100, 30)]; lbUserName.text=@"用户名:"; [self.view addSubview:lbUserName]; _txtUserName=[[UITextField alloc]initWithFrame:CGRectMake(120, 150, 150, 30)]; _txtUserName.borderStyle=UITextBorderStyleRoundedRect; [self.view addSubview:_txtUserName]; //密码 UILabel *lbPassword=[[UILabel alloc]initWithFrame:CGRectMake(50, 200, 100, 30)]; lbPassword.text=@"密码:"; [self.view addSubview:lbPassword]; _txtPassword=[[UITextField alloc]initWithFrame:CGRectMake(120, 200, 150, 30)]; _txtPassword.secureTextEntry=YES; _txtPassword.borderStyle=UITextBorderStyleRoundedRect; [self.view addSubview:_txtPassword]; //登陆按钮 UIButton *btnLogin=[UIButton buttonWithType:UIButtonTypeSystem]; btnLogin.frame=CGRectMake(70, 270, 80, 30); [btnLogin setTitle:@"登陆" forState:UIControlStateNormal]; [self.view addSubview:btnLogin]; [btnLogin addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside]; //取消登陆按钮 UIButton *btnCancel=[UIButton buttonWithType:UIButtonTypeSystem]; btnCancel.frame=CGRectMake(170, 270, 80, 30); [btnCancel setTitle:@"取消" forState:UIControlStateNormal]; [self.view addSubview:btnCancel]; [btnCancel addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside]; } #pragma mark 登陆操做 -(void)login{ if ([_txtUserName.text isEqualToString:@"kenshincui"] && [_txtPassword.text isEqualToString:@"123"] ) { //调用代理方法传参 [self.delegate showUserInfoWithUserName:_txtUserName.text]; [self dismissViewControllerAnimated:YES completion:nil]; } else{ //登陆失败弹出提示信息 UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"系统信息" message:@"用户名或密码错误,请从新输入!" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil]; [alertView show]; } } #pragma mark 点击取消 -(void)cancel{ [self dismissViewControllerAnimated:YES completion:nil]; } @end
在上面的代码中,点击登陆能够跳转到登陆界面,若是用户名、密码输入正确能够回传参数到主界面中(不正确则给出提示),同时修改主界面按钮显示内 容。若是已经登陆则点击注销会弹出提示,点击肯定注销则会注销登陆信息。在代码中咱们还用到了UIActionSheet和UIAlert,这两个控件其 实也是模态窗口,只是没有铺满全屏,你们之后的开发中会常常用到。
假设登陆以后在主视图控制器右上角点击“我”能够弹出当前用户信息如何实现呢?这个时候咱们须要从主视图控制器传递参数到子视图控制器,和前面的传参恰好相反,这个时候咱们一般使用上面提到的第五个方法,设置目标视图控制器的属性。
1.首先修改一下主视图控制器
//
// KCMainViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCMainViewController.h" #import "KCLoginViewController.h" #import "KCMeViewController.h" @interface KCMainViewController ()<KCMainDelegate,UIActionSheetDelegate>{ UILabel *_loginInfo; UIBarButtonItem *_loginButton; UIBarButtonItem *_meButton; BOOL _isLogon; } @end @implementation KCMainViewController - (void)viewDidLoad { [super viewDidLoad]; [self addNavigationBar]; [self addLoginInfo]; } #pragma mark 添加信息显示 -(void)addLoginInfo{ _loginInfo =[[UILabel alloc]initWithFrame:CGRectMake(0, 100,320 ,30)]; _loginInfo.textAlignment=NSTextAlignmentCenter; [self.view addSubview:_loginInfo]; } #pragma mark 添加导航栏 -(void)addNavigationBar{ //建立一个导航栏 UINavigationBar *navigationBar=[[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, 320, 44+20)]; //navigationBar.tintColor=[UIColor whiteColor]; [self.view addSubview:navigationBar]; //建立导航控件内容 UINavigationItem *navigationItem=[[UINavigationItem alloc]initWithTitle:@"Web Chat"]; //左侧添加登陆按钮 _loginButton=[[UIBarButtonItem alloc]initWithTitle:@"登陆" style:UIBarButtonItemStyleDone target:self action:@selector(login)]; navigationItem.leftBarButtonItem=_loginButton; //左侧添加导航 _meButton=[[UIBarButtonItem alloc]initWithTitle:@"我" style:UIBarButtonItemStyleDone target:self action:@selector(showInfo)]; _meButton.enabled=NO; navigationItem.rightBarButtonItem=_meButton; //添加内容到导航栏 [navigationBar pushNavigationItem:navigationItem animated:NO]; } #pragma mark 登陆操做 -(void)login{ if (!_isLogon) { KCLoginViewController *loginController=[[KCLoginViewController alloc]init]; loginController.delegate=self;//设置代理 //调用此方法显示模态窗口 [self presentViewController:loginController animated:YES completion:nil]; }else{ //若是登陆以后则处理注销的状况 //注意必须实现对应代理 UIActionSheet *actionSheet=[[UIActionSheet alloc]initWithTitle:@"系统信息" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"注销" otherButtonTitles: nil]; [actionSheet showInView:self.view]; } } #pragma mark 点击查看个人信息 -(void)showInfo{ if (_isLogon) { KCMeViewController *meController=[[KCMeViewController alloc]init]; meController.userInfo=_loginInfo.text; [self presentViewController:meController animated:YES completion:nil]; } } #pragma mark 实现代理方法 -(void)showUserInfoWithUserName:(NSString *)userName{ _isLogon=YES; //显示登陆用户的信息 _loginInfo.text=[NSString stringWithFormat:@"Hello,%@!",userName]; //登陆按钮内容改成“注销” _loginButton.title=@"注销"; _meButton.enabled=YES; } #pragma mark 实现注销方法 -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ if (buttonIndex==0) {//注销按钮 _isLogon=NO; _loginButton.title=@"登陆"; _loginInfo.text=@""; _meButton.enabled=NO; } } @end
2.添加展现用户信息的控制器视图
KCMeViewController.h
//
// KCMeViewController.h
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import <UIKit/UIKit.h> @interface KCMeViewController : UIViewController #pragma mark 须要传递的属性参数(不少时候它是一个数据模型) @property (nonatomic,copy) NSString *userInfo; @end
KCMeViewController.m
//
// KCMeViewController.m
// ViewTransition
//
// Created by Kenshin Cui on 14-3-15.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#import "KCMeViewController.h" @interface KCMeViewController (){ UILabel *_lbUserInfo; } @end @implementation KCMeViewController - (void)viewDidLoad { [super viewDidLoad]; //信息显示标签 _lbUserInfo =[[UILabel alloc]initWithFrame:CGRectMake(0, 100,320 ,30)]; _lbUserInfo.textAlignment=NSTextAlignmentCenter; _lbUserInfo.textColor=[UIColor colorWithRed:23/255.0 green:180/255.0 blue:237/255.0 alpha:1]; [self.view addSubview:_lbUserInfo]; //关闭按钮 UIButton *btnClose=[UIButton buttonWithType:UIButtonTypeSystem]; btnClose.frame=CGRectMake(110, 200, 100, 30); [btnClose setTitle:@"关闭" forState:UIControlStateNormal]; [btnClose addTarget:self action:@selector(close) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btnClose]; //设置传值信息 _lbUserInfo.text=_userInfo; } #pragma mark 关闭 -(void)close{ [self dismissViewControllerAnimated:YES completion:nil]; } @end
前面代码中除了演示了模态窗口的使用还演示了两种多视图参数传递方法,其余方法往后咱们再作介绍。最后完整展示一下整个示例程序: