如何推送两个视图控制器,但仅为第二个控制器设置动画转换?

时间:2014-02-18 14:46:44

标签: ios objective-c cocoa-touch storyboard uikit

我在storyboad中有三个控制器(FirstVC,SecondVC,ThirdVC),导航是顺序的:用户可以从FirstVC导航到SecondVC,然后导航到ThirdVC。现在,我需要制作一些按钮,它将从FirstVC打开ThirdVC,但也会将SecondVC放在导航堆栈上,所以当用户从ThirdVC按回来时,他将返回到SecondVC。因此,我不需要从FirstVC到SecondVC的动画,只需要在导航控制器堆栈上推送SecondVC,然后仅动画转换到ThirdVC。

我无法找到如何禁用performSegueWithIdentifier的动画,所以我想我应该手动从storyboard实例化SecondVC,将它放在导航堆栈上,然后为ThirdVC执行performSegueWithIdentifier。任何想法如何做到这一点?

7 个答案:

答案 0 :(得分:77)

如果您在第一个VC中,那么您正在寻找解决方案:

NSMutableArray *controllers = [self.navigationController.viewControllers mutableCopy];
[controllers addObject:secondVc];
[controllers addObject:thirdVC];
[self.navigationController setViewControllers:controllers animated:YES];

这将在第三个VC中生成动画,而不会在此过程中显示第二个VC。当用户按下后退按钮时,它们将返回到第二个VC

答案 1 :(得分:25)

保留用于推送视图控制器的标准动画,在Swift中

let pushVC = UIViewController()
let backVC = UIViewController()

if let navigationController = navigationController {

  navigationController.pushViewController(pushVC, animated: true)

  let stackCount = navigationController.viewControllers.count
  let addIndex = stackCount - 1
  navigationController.viewControllers.insert(backVC, atIndex: addIndex)

}

这会正常显示pushVC并将backVC插入导航堆栈,同时保留UINavigationController的动画和历史记录。

您可以使用setViewControllers,但您将失去标准推送动画。

答案 2 :(得分:6)

来自KimAMartinsen解决方案的Swift版本

let firstVC = self.storyboard?.instantiateViewController(withIdentifier: "Tests") as! firstViewController

let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "Dashboard") as! SecondViewController

var controllers = self.navigationController?.viewControllers
controllers?.append(firstVC)
controllers?.append(secondVC)
self.navigationController?.setViewControllers(controllers!, animated: true)

答案 3 :(得分:4)

extension UINavigationController {
    open func pushViewControllers(_ inViewControllers: [UIViewController], animated: Bool) {
        var stack = self.viewControllers
        stack.append(contentsOf: inViewControllers)
        self.setViewControllers(stack, animated: animated)
    }
}

答案 4 :(得分:2)

嗯,或许只是写一个不做任何动画的自定义segue,确保故事板中的segue引用你的segue类。

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomSegues/CreatingCustomSegues.html

上面链接到如何创建它,文档IMO是相当自我解释的。然后,您可以自定义分段工作和显示的方式。

其他选项包括iOS7中引入的新协议,假设您不想支持旧设备。

观看Apple Tech Talks 2014视频“架构现代应用程序第1部分”,他们在那里进行演示。

https://developer.apple.com/tech-talks/videos/

你的问题有很多解决方案,希望以上其中一个是有用的,如果不是,请告诉我,我会提出另一个。

更新:

另一个选择是使用tav视图控制器,如果这符合您的需要,因为您可以将导航控制器添加到其中一个选项卡以实现此功能或根据需要交换选项卡。

答案 5 :(得分:0)

我建议手动推送视图控制器。第一个没有动画:

[self.navigationController pushViewController:SecondVC animated:NO];
[self.navigationController pushViewController:ThirdVC animated:YES];

答案 6 :(得分:0)

我使用以下代码段推送多个View Controller:

extension UINavigationController {
    func push(_ viewControllers: [UIViewController]) {
        setViewControllers(self.viewControllers + viewControllers, animated: true)
    }

    // Also had this in here, left it in as a bonus :)
    func popViewControllers(_ count: Int) {
        guard viewControllers.count > count else { return }
        popToViewController(viewControllers[viewControllers.count - count - 1], animated: true)
    }
}