如果数据模型中有任何已保存的数据,我正在尝试呈现ViewController
。但是我收到以下错误:
警告:尝试显示其视图不在窗口层次结构中的* on *
相关代码:
override func viewDidLoad() {
super.viewDidLoad()
loginButton.backgroundColor = UIColor.orangeColor()
var request = NSFetchRequest(entityName: "UserData")
request.returnsObjectsAsFaults = false
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var results:NSArray = context.executeFetchRequest(request, error: nil)!
if(results.count <= 0){
print("Inga resultat")
} else {
print("SWITCH VIEW PLOX")
let internVC = self.storyboard?.instantiateViewControllerWithIdentifier("internVC") as internViewController
self.presentViewController(internVC, animated: true, completion: nil)
}
}
我尝试过使用谷歌找到的不同解决方案但没有成功。
此时,在代码中,视图控制器的视图仅已创建,但未添加到任何视图层次结构中。如果你想尽快从那个视图控制器出现,你应该在viewDidAppear
中做到最安全。
let storyboard = UIStoryboard(name: "test", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "teststoryboard") as UIViewController
UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
这似乎有助于确保它是最顶级的观点。
我收到了一个错误
警告:尝试在myapp.testController上显示myapp.testController:0x7fdd01703990:0x7fdd01703690,其视图不在窗口层次结构中!
希望这有助于其他人迅速3
我尝试了很多方法!唯一有用的是:
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
}
当你有UINavigationController
或UITabBarController
时,topViewController的所有实现都不是完全支持的情况,对于那两个你需要稍微不同的处理:
对于UITabBarController
和UINavigationController
,您需要一个不同的实现。
这是我用来获取topMostViewController的代码:
protocol TopUIViewController {
func topUIViewController() -> UIViewController?
}
extension UIWindow : TopUIViewController {
func topUIViewController() -> UIViewController? {
if let rootViewController = self.rootViewController {
return self.recursiveTopUIViewController(from: rootViewController)
}
return nil
}
private func recursiveTopUIViewController(from: UIViewController?) -> UIViewController? {
if let topVC = from?.topUIViewController() { return recursiveTopUIViewController(from: topVC) ?? from }
return from
}
}
extension UIViewController : TopUIViewController {
@objc open func topUIViewController() -> UIViewController? {
return self.presentedViewController
}
}
extension UINavigationController {
override open func topUIViewController() -> UIViewController? {
return self.visibleViewController
}
}
extension UITabBarController {
override open func topUIViewController() -> UIViewController? {
return self.selectedViewController ?? presentedViewController
}
}
可以使用,而不是找到顶视图控制器
viewController.modalPresentationStyle = UIModalPresentationStyle.currentContext
其中viewController是你想要呈现的控制器当像TabBar,NavBar这样的层次结构中存在不同类型的视图时这很有用,尽管其他视图似乎是正确的但更多的是hackish
另一种演示风格可以在apple doc上找到
先前的答案涉及应该呈现视图1)的视图控制器尚未添加到视图层次结构的情况,或者2)不是顶视图控制器。 另一种可能性是,在已经呈现另一个警报但尚未解除警报时应该发出警报。
在目标c:当在mpmovieplayer上呈现viewcontroller时,这解决了我的问题
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
斯威夫特3
我有这个不断出现作为一个新手,并发现当前加载模态视图,可以被解雇,但切换到根控制器是最好的,如果你不需要显示模态。
我正在使用它
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard?.instantiateViewController(withIdentifier: "MainAppStoryboard") as! TabbarController
present(vc, animated: false, completion: nil)
使用它来代替我的tabController:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let view = storyboard.instantiateViewController(withIdentifier: "MainAppStoryboard") as UIViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
//show window
appDelegate.window?.rootViewController = view
如果您需要在多个故事板屏幕之间切换,只需调整到视图控制器即可。
斯威夫特3。
调用此函数以获取最顶层的视图控制器,然后使该视图控制器存在。
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
用法:
let topVC = topMostController()
let vcToPresent = self.storyboard!.instantiateViewController(withIdentifier: "YourVCStoryboardID") as! YourViewController
topVC.present(vcToPresent, animated: true, completion: nil)
你只需要执行一个延迟选择器 - (0秒工作)。
override func viewDidLoad() {
super.viewDidLoad()
perform(#selector(presentExampleController), with: nil, afterDelay: 0)
}
@objc private func presentExampleController() {
let exampleStoryboard = UIStoryboard(named: "example", bundle: nil)
let exampleVC = storyboard.instantiateViewController(withIdentifier: "ExampleVC") as! ExampleVC
present(exampleVC, animated: true)
}
对于SWIFT
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
斯威夫特4
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
适用于swift 3.0及以上版本
public static func getTopViewController() -> UIViewController?{
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
return topController
}
return nil}
在用户打开深层链接后呈现控制器时,我收到此错误。我知道这不是最好的解决方案,但是如果你在短时间内这里是一个快速修复 - 只需将你的代码包装在asyncAfter
中:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.7, execute: { [weak self] in
navigationController.present(signInCoordinator.baseController, animated: animated, completion: completion)
})
它将给你的呈现控制器时间打电话给viewDidAppear
。