Swift PresentViewController


73

我以编程方式在一个iOS Swift项目中有多个视图控制器。我没有情节提要,如果可能的话,我希望避免使用它们。有没有一种方法可以切换到另一个viewcontroller.swift文件(我们将其称为view2.swift)并使它成为按钮调用的函数的一部分?
我尝试了以下方法:

let storyboard: UIStoryboard = UIStoryboard(name: "myTabBarName", bundle: nil)
let vc: UIViewController = storyboard.instantiateViewControllerWithIdentifier("myVCID") as UIViewController
self.presentViewController(vc, animated: true, completion: nil)

以上适用于情节提要,但我希望再view2.swift调用另一个。能做到吗?

Answers:


120

尝试这个:

let vc = ViewController() //change this to your class name
self.presentViewController(vc, animated: true, completion: nil)

使用Swift3:

self.present(vc, animated: true, completion: nil)

3
我建议使用初始化程序:ViewController(nibNameOrNil: nil, bundleOrNil: nil)
Simon Germain 2014年

23
@Adam,我所做的完全相同,以显示单击按钮时的视图。它显示黑色空白屏幕。没有错误。知道为什么我会出现黑屏吗?
桑吉瓦尼2014年

2
@Sanjivani,从iOS7开始,视图的默认颜色为纯色,因此显示为黑屏。在VIewController的viewDidLoad中将颜色设置为覆盖功能func viewDidLoad(){super.viewDidLoad()self.view.backgroundColor = UIColor.greenColor()}
Shanmugaraja G

4
这会出现黑屏!
Mojtabye 2015年

1
如何接受并投票这么多次,它甚至没有使用viewcontroller的初始化方法,这样做不会产生任何结果
Tj3n

104

对于那些黑屏/黑屏的用户,此代码对我有用。

    let vc = self.storyboard?.instantiateViewController(withIdentifier: myVCID) as! myVCName
    self.present(vc, animated: true, completion: nil)

要将“标识符”设置为您的VC,只需在情节提要中转到VC的身份检查器即可。将“ Storyboard ID”设置为您想要的标识符。请看下面的图片以供参考。


5
@KD。除非问题要求没有情节提要来执行此操作。
苏拉奇

20

供参考,因为该问题是Google的第一个结果。

Swift 3中的重大变化

用方法presentViewController代替该方法present

您可以像旧版本一样使用它:

self.present(viewControllerToPresent, animated: true, completion: nil)

打开相机的示例:

let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)

15

Swift 3和Swift 4

let vc = self.storyboard?.instantiateViewController(withIdentifier: "idMyViewControllerName") as! MyViewControllerName
self.present(vc, animated: true, completion: nil)

8

对我来说,我在两个单独的导航控制器中有两个视图。我不得不结合使用以上内容。

var vc = self.storyboard?.instantiateViewControllerWithIdentifier("WelcomeViewController") as! WelcomeViewController
    var navigationController = UINavigationController(rootViewController: vc)
    self.presentViewController(navigationController, animated: true, completion: nil)

斯威夫特3.x

        let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "VC-ID" as! yourViewController
        let navigationVC = UINavigationController(rootViewController: secondVC)
        self.present(navigationVC, animated: true, completion: nil)

6

使用Swift 2.1+

 let vc = self.storyboard?.instantiateViewControllerWithIdentifier("settingsVC") as! SettingsViewController
 self.presentViewController(vc, animated: true, completion: nil)

enter image description here


4

通过添加导航控制器并将第二个视图控制器设置为rootVC来解决黑屏问题。

let vc = ViewController()       
var navigationController = UINavigationController(rootViewController: vc)
self.presentViewController(navigationController, animated: true, completion: nil

4

只需使用以下命令:确保使用nibName,否则xib的预加载视图将不会显示:

var vc : ViewController = ViewController(nibName: "ViewController", bundle: nil) //将其更改为您的班级名称

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

0

您可以使用以下代码:

var vc = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController;
            vc.mode_Player = 1
            self.presentViewController(vc, animated: true, completion: nil)

0

另一种可能性是您的构建目标中没有包含XIB(这是我发生的事情)。

如果您对开发,测试和发布版本有不同的目标(无论如何应该有此目标),则可能会发生这种情况。


0

您可以使用以下代码:

if let vc = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as? secondViewController {
   let appDelegate = UIApplication.shared.delegate as! AppDelegate
   appDelegate.window?.rootViewController = vc
}

0

您无需仅在Storyboard中实例化ViewController即可获得 present()ViewController工作。那是一个棘手的解决方案。

如果在显示VC时看到黑屏/黑屏,则可能是因为您是present()viewDidLoad()First / RootViewController中,但是第一个View尚未准备好。

呼叫present()viewDidAppear解决这个问题,即:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let yourVC = YourViewController()
    self.present(yourVC, animated: true, completion: nil)
}

一旦任何“视图”出现在您的应用中,就可以从开始调用present()viewDidLoad()


使用UINavigationController(如答案中所建议的)是另一种选择,但解决该问题可能是一个过大的杀伤力。您可能最终会使用户流程复杂化。UINavigationController仅当您想要拥有NavigatonBar或想要返回到以前的视图控制器时,才使用基于基础的解决方案。


0

我有一个类似的问题,但就我而言,解决方案是将操作作为异步任务分派到主队列中

DispatchQueue.main.async {
    let vc = self.storyboard?.instantiateViewController(withIdentifier: myVCID) as! myVCName
    self.present(vc, animated: true, completion: nil)
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.