之前的文章是针对UINavigationController利用拖线的方式执行push操作进行页面跳转来讲解的。本文将继续通过UINavigationController的页面跳转来深刻讲解拖线执行push的跳转原理。
现在我们就来讲解一下这条线的有关知识。
storyboard上每一根用来界面跳转的线,都是一个UIStoryboardSegue对象(简称Segue)。每一个Segue对象,都有3个属性
唯一标识
@property (nonatomic, readonly) NSString *identifier;
来源控制器
@property (nonatomic, readonly) id sourceViewController;
目标控制器
@property (nonatomic, readonly) id destinationViewController;
三个属性对应的图如下:
根据Segue的执行(跳转)时刻,Segue可以分为2大类型
自动型:点击某个控件后(比如按钮),自动执行Segue,自动完成界面跳转
手动型:需要通过写代码手动执行Segue,才能完成界面跳转
1> 自动型:按住Control键,直接从控件拖线到目标控制器(控件 ->目标控制器)
介绍:点击“登录”按钮后,就会自动跳转到右边的控制器(一定跳转)
使用:如果点击某个控件后,不需要做任何判断,一定要跳转到下一个界面,建议使用“自动型Segue”。
2>手动型:按住Control键,从来源控制器拖线到目标控制器(源控制器 ->目标控制器)
手动型的Segue需要设置一个标识(如下图)
介绍:在恰当的时刻,使用perform方法执行对应的Segue。[self performSegueWithIdentifier:@"one2two" sender:nil];(不一定要跳转)
注意:Segue必须由来源控制器来执行,也就是说,这个perform方法必须由来源控制器来调用
使用:如果点击某个控件后,需要做一些判断,也就是说:满足一定条件后才跳转到下一个界面,建议使用“手动型Segue”
拖完线、设置完identifier之后页面也不一定会跳转。下面介绍一下performSegueWithIdentifier:sender方法:利用performSegueWithIdentifier:方法可以执行某个Segue,完成界面跳转接下来研究performSegueWithIdentifier:sender:方法的完整执行过程[self performSegueWithIdentifier:@“one2two” sender:nil];(这个self是来源控制器)
1. 根据identifier(@”one2two”)去storyboard中找到对应的线,新建UIStoryboardSegue对象
b.设置Segue对象的sourceViewController(来源控制器)
c.新建并且设置Segue对象的destinationViewController(目标控制器)
- (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender;//这个sender是当初performSegueWithIdentifier:sender:中传入的sender
3.调用Segue对象的- (void)perform;方法开始执行界面跳转操作
(1) 如果segue的style是push
a.取得sourceViewController所在的UINavigationController
b.调用UINavigationController的push方法将destinationViewController压入栈中,完成跳转
(2) 如果segue的style是modal
a.调用sourceViewController的presentViewController方法将destinationViewController展示出来
下面就用一个项目来使用segue执行跳转,开始写代码:(登录功能)
1、创建项目:
功能介绍:
- 当点击登录按钮时,需要判断账号是否为“shx”,密码是否为“123”(正确的账号、密码:shx/123)。如果账号或者密码错误,则页面不跳转,如果账号和密码正确,则跳转至登录成功界面(destinationViewController);
- 当点击注册按钮时,大家都知道,一定会跳转到注册页面(destinationViewController)。
(1)注册按钮:按住Control键,直接从注册按钮拖线到注册控制器页面(destinationViewController);选择Action Segue -> show
(2)登录按钮:由于点击登录按钮不一定发生跳转,所以不能直接从登录按钮拖线。正确做法:从登录控制器(sourceViewController)开始拖线至登录成功控制器(destinationViewController):选择manual Segue -> show
3、为每个控制器创建一个控制器类,并设置控制器类名
4、运行程序后发现,我们只是给注册按钮拖了一条线到注册控制器(destinationViewController),注册按钮的功能就已经实现了。主要点击注册按钮,就一定会跳转到注册界面。但是登录按钮呢,不管怎么点都没有反应。前面说过,“手动型Segue”需要在源控制器总实现一个方法之后,按钮点击才会有反应。
5、现在实现登录按钮功能:
(1)首先为登录按钮的manual Segue添加标示”login2succeed”,
(2) 再在登录控制器中实现按钮点击的方法(拖线实现按钮点击,应该没有问题吧)。应该我们还要对账号和密码进行判断,所以我们也要拿到账号和密码的属性(还是拖线)。在按钮点击的方法中对账号和密码进行判断。
代码如下:
- (IBAction)clickLogin {
// 如果账号为空或不为shx,则返回,不作任何处理
if ([self.accountField.text isEqualToString:@""] ||![self.accountField.text isEqualToString:@"shx"]) {
return;
}
// 如果密码为空或不为123,则返回,不作任何处理
if ([self.pwdField.text isEqualToString:@""] ||![self.pwdField.text isEqualToString:@"123"]) {
return;
}
// 如果账号和密码正确,则需要需要跳转至登录成功页面,sender先传nil
[self performSegueWithIdentifier:@"login2succeed" sender:nil];
}
6、再运行程序:
(1) 账号或密码错误的时候,点击登录按钮没有任何反应。
(2) 账号和密码正确的时候,点击登录按钮,进行登录成功界面。
利用segue执行的push(show)操作到这里就讲解完了。其实除了push(show)之外,还有另外一种控制器的切换方式,那就是Modal。任何控制器都能通过Modal的形式展示出来。Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止
以Modal的形式展示控制器
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void(^)(void))completion
关闭当初Modal出来的控制器
-(void)dismissViewControllerAnimated: (BOOL)flag completion: (void(^)(void))completion;