当我们写项目时经常会使用界面切换来切换不同的视图,当我们需要切换到下一个视图的时候有两种方法,第一种是push第二种是pop。
Push 是在导航控制器(UINavigationController)中使用的界面切换方式,它可以将一个新的视图控制器压入导航栈中并作为栈顶元素显示在屏幕上,当使用push的时候系统会自动在右上角生成返回上一级的按钮,此按钮也可以用重写的pop按钮覆盖。
代码格式如下:
其中vc是下一级视图的对象
[self.navigationController pushViewController:vc animated:YES];
Present 是在模态视图(Modal)中使用的界面切换方式,它可以让用户在一个新的视图控制器中完成某些操作,然后再返回到原来的视图控制器。Present 需要手动添加关闭模态视图的按钮。
代码格式如下:
其中newViewController是下一级视图的对象
[self presentViewController:newViewController animated:YES completion:nil];
当我们需要返回上一级或者指定视图时也需要切换视图,此时我们也有两种方法,第一种是pop,与push相对应;第二种是dismiss,与present相对应。
Pop 是在导航控制器中使用的界面返回方式,它可以将当前视图控制器从导航栈中弹出,并返回到前一个视图控制器。Pop 的特点是可以通过导航栏自动提供的返回按钮返回到上一个视图控制器,也可以使用自定义的导航栏按钮返回到上一个视图控制器。
代码格式如下:
其中vc是指定的视图控制器对象
//返回到上一级视图控制器
[self.navigationController popViewControllerAnimated:YES];
//返回到指定视图控制器
[self.navigationController popToViewController:vc animated:YES];
Dismiss 是在模态视图中使用的界面返回方式,它可以将当前的模态视图关闭,并返回到原来的视图控制器。我们需要在当前视图添加按钮来触发事件函数返回到使用present推出视图控制器的那个视图控制器。也就是说假如我们在第一级视图用present推出第三级视图,当我们在第三级视图使用dismiss返回上一级时,返回的是第一级视图而不是第二级视图。
代码格式如下:
[self dismissViewControllerAnimated:YES completion:nil];
此处我创建了三个视图控制器并将导航控制器作为window窗口的根视图将第一个视图控制器作为导航控制器的根视图。接着在第一级视图通过push推出第二级视图,在第二级视图返回第一级视图或使用present推出第三级视图,最后使用dismiss返回到使用present方法的那个视图。
FirstViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface FirstViewController : UIViewController
@property (nonatomic, strong)UIBarButtonItem* btnNext;
@end
NS_ASSUME_NONNULL_END
FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
_btnNext = [[UIBarButtonItem alloc] initWithTitle:@"next" style:UIBarButtonItemStyleDone target:self action:@selector(pressNext)];
self.navigationItem.rightBarButtonItem = _btnNext;
}
- (void)pressNext {
SecondViewController* viewSecond = [[SecondViewController alloc] init];
[self.navigationController pushViewController:viewSecond animated:YES];
}
@end
视图一如下:
接着我们按next按钮切换到下一级视图
SecondViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SecondViewController : UIViewController
@property (nonatomic, strong)UIButton* btnNextTwo;
@end
NS_ASSUME_NONNULL_END
SecondViewController.m
#import "SecondViewController.h"
#import "ThirdViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor greenColor];
_btnNextTwo = [UIButton buttonWithType:UIButtonTypeRoundedRect];
_btnNextTwo.frame = CGRectMake(120, 200, 120, 40);
[_btnNextTwo setTitle:@"next" forState:UIControlStateNormal];
[_btnNextTwo addTarget:self action:@selector(pressNextTwo) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_btnNextTwo];
}
- (void)pressNextTwo {
ThirdViewController* viewThird = [[ThirdViewController alloc] init];
[self presentViewController:viewThird animated:YES completion:nil];
}
@end
视图二如下:
我们可以点击back返回上一级视图也可以点击next切换到下一级视图,这里我们切换到下一级视图
ThirdViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ThirdViewController : UIViewController
@property (nonatomic, strong)UIButton* btnBack;
@end
NS_ASSUME_NONNULL_END
ThirdViewController.m
#import "ThirdViewController.h"
@interface ThirdViewController ()
@end
@implementation ThirdViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blueColor];
_btnBack = [UIButton buttonWithType:UIButtonTypeRoundedRect];
_btnBack.frame = CGRectMake(120, 200, 120, 40);
[_btnBack setTitle:@"back" forState:UIControlStateNormal];
[_btnBack addTarget:self action:@selector(pressBack) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_btnBack];
}
- (void)pressBack {
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
视图三如下:
可以看到此时的视图并不是全屏的,这个就是模态视图,个人理解就是相当于一个临时的覆盖在原来视图上的一个新的视图。
如果想让它变成全屏效果可通过如下代码实现:
viewThird.modalPresentationStyle = UIModalPresentationFullScreen;
当我们点击back即可返回第二级视图也就是使用present推出方法的那个视图。
总结一下就是push和pop绑在一起,需要通过导航控制器来使用。present和dismiss捆在一起,需要在视图中设置按钮触发事件函数来调用。
pop返回的是使用push的那个视图控制器,dismiss返回的是使用present的那个视图控制器。