iOS頁面跳轉(zhuǎn)方式
[self presentViewController:viewController animated:YES completion:nil];
[self.navigationController pushViewController:viewController animated:YES];
通常使用第2種方式鬼雀,NavigationController已經(jīng)幫我們管理了頁面跳轉(zhuǎn)形成的view controller的棧并且也提供了跳轉(zhuǎn)实撒、回退到棧內(nèi)指定頁面的方法:
//返回到上一個(gè)頁面
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;
//返回到根頁面
- (NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated;
//返回到棧內(nèi)指定的UIViewController頁面
- (NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
//返回到棧內(nèi)指定的UIViewController時(shí)靴患,棧內(nèi)該UIViewController上面的所有頁面都會(huì)出棧,并且參數(shù)viewController必須要保證在棧內(nèi)
//跳轉(zhuǎn)到指定頁面常用方式1:
for (UIViewController *vc in self.navigationController.viewControllers) {
if ([vc isKindOfClass:[yourTargetViewController class]]) {
[self.navigationController popToViewController:vc animated:YES];
return;
}
}
//跳轉(zhuǎn)到指定頁面常用方式2(如果知道指定頁面在棧內(nèi)索引位置):
UIViewController *targetVC = self.navigationController.viewControllers[1];
//UIViewController *targetVC = [self.navigationController.viewControllers objectAtIndex:1];
[self.navigationController popToViewController:targetVC animated:YES];
使用第1種presentViewController方式需要先理解:
//UIViewController內(nèi)有屬性
@property(nonatomic, readonly) UIViewController *presentingViewController;
@property(nonatomic, readonly) UIViewController *presentedViewController;
When you present a view controller modally (either explicitly or implicitly) using the
presentViewController:animated:completion:
method, the view controller that called the method has this property set to the view controller that it presented. If the current view controller did not present another view controller modally, the value in this property isnil
.
簡(jiǎn)單來說就是:
[controllerA presentViewController:controllerB animated:YES completion:nil];
controllerB.presentingViewController = controllerA;
controllerA.presentedViewController = controllerB;
controllerB.presentedViewController = nil;
理解上面的屬性之后再看函數(shù):
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion;
官方說明:
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal.
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
If you want to retain a reference to the view controller'??s presented view controller, get the value in thepresentedViewController
property before calling this method.
The completion handler is called after theviewDidDisappear:
method is called on the presented view controller.
通俗點(diǎn)理解就是:
頁面controllerB的dismiss由展示它的頁面controllerB.presentingViewController負(fù)責(zé):
//在controllerB內(nèi)執(zhí)行下面的方法其實(shí)是由controllerB.presentingViewController負(fù)責(zé)處理的
[self dismissViewControllerAnimated:YES completion:nil];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
//上述兩行代碼的效果是一樣的豁状,都是退出controllerB頁面
如果使用present方式展示了很多個(gè)頁面捉偏,形成了一個(gè)由presentedViewController形成的棧。
若在棧內(nèi)某個(gè)viewControllerD(非棧頂)調(diào)用了該方法泻红,將會(huì)dismiss它的直接child即(viewControllerD.presentedViewController)以及其上面的所有viewController夭禽。
綜合上面的信息就可以實(shí)現(xiàn)跳轉(zhuǎn)到指定viewContoller:
//直接回到根視圖
UIViewController *rootVC = self.presentingViewController;
while (rootVC.presentingViewController) {
//根視圖的presentingViewController為nil退出循環(huán)
rootVC = rootVC.presentingViewController;
}
[rootVC dismissViewControllerAnimated:YES completion:nil];
//跳轉(zhuǎn)到指定的targetViewController
UIViewController *targetVC = self.presentingViewController;
while ( ![targetVC isKindOfClass:[targetViewController class]] ) {
targetVC = targetVC.presentingViewController;
}
[targetVC dismissViewControllerAnimated:YES completion:nil];