Swift 以编程方式导航到另一个视图控制器/场景

Posted

技术标签:

【中文标题】Swift 以编程方式导航到另一个视图控制器/场景【英文标题】:Swift programmatically navigate to another view controller/scene 【发布时间】:2017-01-19 21:07:20 【问题描述】:

我正在使用以下代码以编程方式导航到另一个 ViewController。它工作正常,但它有些隐藏navigation bar我该如何解决这个问题?(导航栏是通过在navigation controller 中嵌入ViewController 来创建的。)

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("nextView") as NextViewController
self.presentViewController(nextViewController, animated:true, completion:nil)

【问题讨论】:

【参考方案1】:

斯威夫特 5

默认的模态展示样式是卡片。这在顶部显示了先前的视图控制器,并允许用户滑动显示的视图控制器。

要保留旧样式,您需要修改将要呈现的视图控制器,如下所示:

newViewController.modalPresentationStyle = .fullScreen

这对于以编程方式创建的控制器和情节提要创建的控制器都是一样的。

斯威夫特 3

使用以编程方式创建的控制器

如果您想导航到以编程方式创建的控制器,请执行以下操作:

let newViewController = NewViewController()
self.navigationController?.pushViewController(newViewController, animated: true)

使用 StoryBoard 创建的控制器

如果您想使用标识符“newViewController”导航到 StoryBoard 上的控制器,请执行以下操作:

let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
        self.present(newViewController, animated: true, completion: nil)

【讨论】:

"as!NewViewController" 在情节提要选项中不需要 是的,我知道这是可选的,但是如果我们显示,那么哪个 viewcontroller 是另一个开发人员的目的地就很清楚了 从主线程调用storyBoard.instantiateViewControllerself.present,否则viewController组件会出现延迟 @Alex 看,开发人员可以从主线程调用它,我刚刚写了上面问题的答案。您从主线程调用的评论在这里不合适。 嗨 peeps:作为一般规则,我可以建议一个更友好的语气吗? (这在 SO 上是一个相当大的问题)相反的话题:虽然它不是由 OP 直接询问的,但我认为这个好的答案仍然是一个合适的地方来记住(对于任何阅读的人)必须在主线程上发生的动作 【参考方案2】:

SWIFT 4.x

双引号中的字符串总是让我感到困惑,所以我认为这个问题的答案需要一些图形演示来解决这个问题。

对于银行应用程序,我有一个 LoginViewController 和一个 BalanceViewController。每个都有各自的屏幕。

应用程序启动并显示登录屏幕。登录成功后,应用会打开余额界面。

这是它的外观:

登录成功是这样处理的:

let storyBoard: UIStoryboard = UIStoryboard(name: "Balance", bundle: nil)
let balanceViewController = storyBoard.instantiateViewController(withIdentifier: "balance") as! BalanceViewController
self.present(balanceViewController, animated: true, completion: nil)

如您所见,小写字母的情节提要 ID 'balance' 位于代码的第二行,这是情节提要设置中定义的 ID,如所附屏幕截图所示。

大写“B”的“平衡”一词是故事板文件的名称,用于代码的第一行。

我们知道在代码中使用硬编码字符串是一种非常糟糕的做法,但不知何故在 ios 开发中它已成为一种常见做法,Xcode 甚至不会警告它们。

【讨论】:

精彩演示 哥们你太棒了! 谢谢你!根据接受的答案不知道该怎么做...【参考方案3】:

您应该使用当前的导航控制器推送新的视图控制器,而不是当前。

self.navigationController.pushViewController(nextViewController, animated: true)

【讨论】:

为什么要推送有什么好处? @DragonFire,因为 op 希望它在不覆盖导航栏的情况下工作。如果您想在 whatsapp 联系人屏幕和聊天屏幕之间进行主详细信息页面设计,您必须 push 带有导航控制器的视图控制器。 (从左到右动画)如果你只想在当前屏幕上显示、呈现、弹出(从下到上动画),只需使用present 谢谢!保持我的导航控制器选项卡等是一种享受。【参考方案4】:

根据@jaiswal Rajan 在his answer 中的说法。你可以像这样做一个 pushViewController:

let storyBoard: UIStoryboard = UIStoryboard(name: "NewBotStoryboard", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "NewViewController") as! NewViewController
self.navigationController?.pushViewController(newViewController, animated: true)

【讨论】:

嗨,只是想知道:为什么要重复已经发布的答案?也许评论或赞成也可以。还是背后有进一步的原因? 他正在展示使用 NavigationController 进行导航。谢谢。【参考方案5】:

因此,如果您呈现视图控制器,它将不会显示在导航控制器中。它只需要完整的屏幕。对于这种情况,您必须创建另一个导航控制器并将您的 nextViewController 添加为根并显示这个新的导航控制器。

另一种方法是只推送视图控制器。

self.presentViewController(nextViewController, animated:true, completion:nil)

有关更多信息,请查看 Apple 文档:- https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/doc/uid/TP40006926-CH3-SW96

【讨论】:

presentViewController 已重命名为 present(loginController, animated:true, completion:nil)【参考方案6】:
OperationQueue.main.addOperation 
   let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
   let newViewController = storyBoard.instantiateViewController(withIdentifier: "Storyboard ID") as! NewViewController
   self.present(newViewController, animated: true, completion: nil)

当我将代码放在OperationQueue.main.addOperation 中时,它对我有用,它将在我的主线程中执行。

【讨论】:

【参考方案7】:

所有其他答案听起来都不错,我想介绍一下我的情况,我必须制作一个动画 LaunchScreen,然后在 3 到 4 秒的动画之后,下一个任务是移动到主屏幕。我尝试了 segues,但这给目标视图带来了问题。所以最后我访问了 AppDelegates 的 Window 属性,并为它分配了一个新的 NavigationController 屏幕,

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomePageViewController") as! HomePageViewController

//Below's navigationController is useful if u want NavigationController in the destination View
let navigationController = UINavigationController(rootViewController: homeVC)
appDelegate.window!.rootViewController = navigationController

如果您不想在目标视图中使用 navigationController,则只需指定为,

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomePageViewController") as! HomePageViewController
appDelegate.window!.rootViewController = homeVC

【讨论】:

【参考方案8】:

上面的代码运行良好,但是如果你想从NSObject 类导航,你不能使用self.present

let storyBoard = UIStoryboard(name:"Main", bundle: nil)
if let conVC = storyBoard.instantiateViewController(withIdentifier: "SoundViewController") as? SoundViewController,
    let navController = UIApplication.shared.keyWindow?.rootViewController as? UINavigationController 
    
    navController.pushViewController(conVC, animated: true)

【讨论】:

以上是关于Swift 以编程方式导航到另一个视图控制器/场景的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式导航到另一个视图控制器/场景

以编程方式导航到另一个故事板上的导航控制器和标签栏控制器内的视图控制器

在 Swift 中单击以编程方式切换到 TableViewCell 上的导航视图

如何在 ios 9 中以编程方式导航到另一个具有“当前上下文”表示的视图控制器,目标 C

在 Swift 中以编程方式将视图添加到 stackview

如何以编程方式插入右键图像UINavigationbar swift 3