在平时编写代码的过程中,页面之间的跳转可以说就和MVC模式一样是开发必须的。但是可能我们知道一种或者几种页面之间的跳转,今天我就来总结一下我在开发之中遇到的所有的页面跳转代码。(关于控制器之间的简单的跳转,比如导航控制器跳转、故事版跳转、简单的模态跳转不在这里多说)
一、代理跳转。
通常我们在跳转中经常是通过你点击了某个事件或者某个操作使你进行控制器之间的跳转。那么我们可以在这个按钮事件或者操作里面写一个代理进行跳转或者传值。
例子:
.h
#import <UIKit/UIKit.h>
@class TestView;
@protocol TestViewDelegate <NSObject>
//跳转控制器
-(void)goToController;
@end
@interface TestView : UIView
//代理
@property(nonatomic,weak)id<TestViewDelegate>delegate;
@end
.m
#import "TestView.h"
@implementation TestView
-(void)layoutSubviews
{
self.backgroundColor = [UIColor lightGrayColor];
//创建一个按钮
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"跳转" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn.frame = CGRectMake(100, 200, 60, 30);
[btn addTarget:self action:@selector(changeView) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
}
//按钮事件
-(void)changeView
{
//代理跳转
if ([self.delegate respondsToSelector:@selector(goToController)]) {
[self.delegate goToController];
}
}
@end
#import "ViewController.h"
#import "TestView.h"
#import "SecViewController.h"
@interface ViewController ()<TestViewDelegate>//声明代理
@property(nonatomic,retain)TestView *testView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//加载视图
[self loadTestView];
}
-(void)loadTestView
{
_testView = [[TestView alloc]initWithFrame:self.view.bounds];
//挂上代理
_testView.delegate = self;
[self.view addSubview:_testView];
}
//代理方法实现
-(void)goToController
{
SecViewController *sec = [[SecViewController alloc]init];
[self.navigationController pushViewController:sec animated:YES];
}
@end
跳转的控制器.m
#import "SecViewController.h"
@interface SecViewController ()
@end
@implementation SecViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
//创建按钮方法
[self loadBtn];
}
-(void)loadBtn
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 300, 60, 30);
[btn setTitle:@"返回" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(returnBtn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)returnBtn
{
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
但是这种跳转的不好之处就在于代理书写代码太过繁琐,你不仅需要在视图A里面写一个代理代码你还需要在控制器B里面去实现代理的方法。
二、block跳转。
大家都知道block块的强大之处,我个人认为block是代理的升级版本。他实现了代理能实现的功能,而且代码更加的简洁。只需要在视图A中进行一次声明然后在控制器B 中进行跳转代码的实现。
代码:
.h
#import <UIKit/UIKit.h>
@class TestView;
@protocol TestViewDelegate <NSObject>
//跳转控制器
-(void)goToController;
@end
@interface TestView : UIView
//代理
@property(nonatomic,weak)id<TestViewDelegate>delegate;
//块跳转
@property(nonatomic,copy)void(^myBlock)();
@end
#import "TestView.h"
@implementation TestView
-(void)layoutSubviews
{
self.backgroundColor = [UIColor lightGrayColor];
//创建一个按钮
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"跳转" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn.frame = CGRectMake(100, 200, 60, 30);
[btn addTarget:self action:@selector(changeView) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
}
//按钮事件
-(void)changeView
{
// //代理跳转
// if ([self.delegate respondsToSelector:@selector(goToController)]) {
// [self.delegate goToController];
// }
//块跳转
self.myBlock();
}
@end
#import "ViewController.h"
#import "TestView.h"
#import "SecViewController.h"
@interface ViewController ()<TestViewDelegate>//声明代理
@property(nonatomic,retain)TestView *testView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//加载视图
[self loadTestView];
}
-(void)loadTestView
{
_testView = [[TestView alloc]initWithFrame:self.view.bounds];
//挂上代理
_testView.delegate = self;
ViewController *vc = self;
_testView.myBlock = ^{
SecViewController *sec = [[SecViewController alloc]init];
[vc presentViewController:sec animated:YES completion:nil];
};
[self.view addSubview:_testView];
}
//代理方法实现
-(void)goToController
{
// SecViewController *sec = [[SecViewController alloc]init];
// [self presentViewController:sec animated:YES completion:nil];
}
@end
#import "SecViewController.h"
@interface SecViewController ()
@end
@implementation SecViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
//创建按钮方法
[self loadBtn];
}
-(void)loadBtn
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 300, 60, 30);
[btn setTitle:@"返回" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(returnBtn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)returnBtn
{
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
但是需要知道的是无论是代理还是block我们都是需要视图和控制器之间存在着联系的,不然没有办法去调用代理或者block。这是大家很容易忽略的地方,也是经常容易错的地方。
三、通知跳转。
我们也可以使用通知进行页面得跳转。通知在我看来就是比代理好的一点就是不需要视图和控制器之间有必然的关联就可以调用(当然他们最大的区别是一个可以多对多传值)。
四、直接在视图跳转
这一个方法是非常的直接,就是在视图中直接的跳转界面。说白了就是调出application然后也是以导航控制器的形式进行跳转。非常的简单实用(当然是在不需要进行传值等操作的时候。)
代码:
视图 .m
#import "TestView.h"
#import "SecViewController.h"
@implementation TestView
-(void)layoutSubviews
{
self.backgroundColor = [UIColor lightGrayColor];
//创建一个按钮
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"跳转" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn.frame = CGRectMake(100, 200, 60, 30);
[btn addTarget:self action:@selector(changeView) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
}
//按钮事件
-(void)changeView
{
// //代理跳转
// if ([self.delegate respondsToSelector:@selector(goToController)]) {
// [self.delegate goToController];
// }
//块跳转
// self.myBlock();
//视图直接涂转控制器
UINavigationController *nav = (UINavigationController *)[UIApplication sharedApplication].keyWindow.rootViewController;
SecViewController *sec = [[SecViewController alloc]init];
[nav pushViewController:sec animated:YES];
}
@end