NavigationContainer icon indicating copy to clipboard operation
NavigationContainer copied to clipboard

bug

Open Yangshaoyi opened this issue 7 years ago • 13 comments

控制器里面调[self removeFromParentViewController];会出问题

Yangshaoyi avatar Nov 02 '18 02:11 Yangshaoyi

有没有办法解决[self removeFromParentViewController];这个问题,因为业务涉及到下订单成功之后跳转需要清除前面些页面的

Yangshaoyi avatar Nov 02 '18 03:11 Yangshaoyi

能否给个demo

xiaopin avatar Nov 02 '18 03:11 xiaopin

可以的,怎么发demo过去给你的

Yangshaoyi avatar Nov 02 '18 03:11 Yangshaoyi

发邮件到 [email protected],下午我找时间看看,解决了我会在这里回复你。

xiaopin avatar Nov 02 '18 03:11 xiaopin

您好!已经给您发过去了,非常感谢!

Yangshaoyi avatar Nov 02 '18 04:11 Yangshaoyi

我刚刚看了,在这个方法加些判断就可以了

  • (NSArray<UIViewController *> *)viewControllers { // 返回真正的控制器给外界 NSMutableArray<UIViewController *> *vcs = [NSMutableArray array]; NSArray<UIViewController *> *viewControllers = [super viewControllers]; for (UIViewController *vc in viewControllers) { if (XPUnwrapViewController(vc)) { [vcs addObject:XPUnwrapViewController(vc)]; } else { [vc removeFromParentViewController]; } } return [NSArray arrayWithArray:vcs]; }

Yangshaoyi avatar Nov 02 '18 05:11 Yangshaoyi

好的,我待会看下

xiaopin avatar Nov 02 '18 05:11 xiaopin

其实你应该这样子编写代码,导航栏返回上一页并不能通过 removeFromParentViewController 方式来处理。

- (void)clickedPay {
    ResultController *vc = [[ResultController alloc] init];
//    [self.navigationController pushViewController:vc animated:YES];
//    [self removeFromParentViewController];
    [self.navigationController popViewControllerAnimated:NO];
    [self.navigationController pushViewController:vc animated:YES];
}

xiaopin avatar Nov 02 '18 06:11 xiaopin

不是,因为这样为了防止手势滑动返回不需要的页面

Yangshaoyi avatar Nov 02 '18 06:11 Yangshaoyi

不太明白防止手势滑动返回不需要的页面这话什么意思,你的代码是先push然后再移除上一个页面,我给你看的代码就是先移除然后再push页面,效果是一样的,都是要把 OrderController 移除掉。

不过你的思路确实很清奇,我没试过用 removeFromParentViewController 来移除导航栏管理的控制器,因为导航栏管理的控制器都是以栈的形式存储的嘛,遵循先进后出的规律,我没想到还可以用你这种方式,原谅我的孤陋寡闻哈。

xiaopin avatar Nov 02 '18 06:11 xiaopin

经过测试,如果采用的是 UINavigationController 而不是 XPRootNavigationController, 你的代码看起来有效,因为当你返回上一页时,确实看不到被移除的页面了(障眼法)。

但是如果你多次点击返回按钮,你会发现此时的导航栏控制器栈已经乱套了,而且导航栏的标题也有问题,具体你可以自己测试体验下。

removeFromParentViewController 本来是和 addChildViewController: 一起出现的,用于自定义控制器容器,而 UINavigationController 提供了push/pop 来管理控制器,所以我们应该严格使用苹果提供的API。

对于你这种场景,我强烈建议你先 pop 然后再 push 新控制器(目前我的项目也是采用这种方式)。当然除了 push/pop ,你也可以直接通过修改 viewControllers 数组的方式来过滤掉控制器,但是不建议你采用 removeFromParentViewController

xiaopin avatar Nov 02 '18 07:11 xiaopin

比如:你push到第十个控制器了,你在第十个控制页面想通过侧滑手势返回到第五个页面,这种pop再push就不太适合了,这种障眼法也还是有效的

Yangshaoyi avatar Nov 02 '18 07:11 Yangshaoyi

针对这种场景,你可以先使用 popToViewController:animated: 方法来返回到特定的控制器,然后再push。或者使用前面提到的直接给 viewControllers 属性赋值;先取出 UINavigationController 的 viewControllers 数组,然后将你不需要的控制器过滤掉,最后把修改后的数组赋值回去。

下面是采用 UINavigationController + removeFromParentViewController 的效果演示,你注意查看返回效果。标题、返回按钮文字以及返回的层级都不对,所以建议不要使用 removeFromParentViewController。 demo

xiaopin avatar Nov 02 '18 07:11 xiaopin