奇怪的自定义segue行为 - 导航堆栈损坏

时间:2012-12-20 00:39:31

标签: iphone objective-c ios uinavigationcontroller uistoryboard

我有一个很大的应用程序,它使用storyboard进行了许多转换。 转换应该是从右到左,所以我做了一个自定义segue来执行它。

当我使用常规转换时,我推入导航堆栈的每个视图控制器都会被保留,直到我弹出它。

虽然使用自定义segues不保留前一个控制器(推送当前控制器的控制器),但当我弹回时,控制器的实例会获得一个不同的内存地址,这表明指针已经改变。

这是自定义推送segue:

UIViewController *sourceViewController = (UIViewController*)[self         sourceViewController];
UIViewController *destinationController = (UIViewController*)[self   destinationViewController];

CATransition* transition = [CATransition animation];
transition.duration = .3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;

[sourceViewController.navigationController.view.layer addAnimation:transition
                                                            forKey:kCATransition];

[sourceViewController.navigationController pushViewController:destinationController animated:NO];

和自定义pop segue:

UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];

CATransition* transition = [CATransition animation];
transition.duration = .3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;

[sourceViewController.navigationController.view.layer addAnimation:transition
                                                            forKey:kCATransition];

[sourceViewController.navigationController pushViewController:destinationController animated:NO];

我用这种方法执行segue:

[self performSegueWithIdentifier:@"SearchToMenu" sender:self];

似乎没什么用,我在网上找不到任何东西。

如果我需要提供更多代码示例,屏幕截图等,请告知我们。

1 个答案:

答案 0 :(得分:0)

您的popViewController正在推送,而不是弹出。

这一行:

 [sourceViewController.navigationController pushViewController:destinationController animated:NO];

应该是:

[sourceViewController.navigationController popViewControllerAnimated:NO];

您的自定义segue会保留以前的控制器。但是segue的destinationController总是一个新实例化的对象。您注意到您为新控制器获取了不同的内存地址,但如果您检查[self.navigationController viewControllers]堆栈,您将看到原始viewController仍然存在,堆栈中有三个对象。在此更正版本中,您将按照预期返回viewContoller的该实例。

这就是为什么你永远不应该使用标准推送segue导航回到堆栈下方的任何地方。虽然故事板会暗示这将会发生,但它是虚幻的:你只是导航到前一个viewController类的新实例。它看起来与前一个状态完全一样,因为它使用相同的Storyboard布局。

你的是一个很好的例子,最好不要使用segue。这不仅令人困惑,而且,当你回弹时,如果你试图在prepareForSegue中配置“destinationViewController”,它对你的popped-back-to viewController没有任何影响。你可能还注意到Storyboard搞砸了,因为它失去了哪个viewController包含在哪个NavController中。你失去了导航栏和完全配置它们的能力(在故事板中 - 它们仍在应用程序中)。