在iOS 13和Xcode 11中呈现视图控制器的问题

3

我正在尝试在最上层的视图控制器(topMostViewController)中展示一个视图控制器(viewcontroller). 这个方法在iOS 12及以下版本是有效的。但是在iOS 13上,我遇到了以下错误:

手动将rootViewController的视图添加到视图层级结构中已不再受支持。请允许UIWindow自行将rootViewController的视图添加到视图层级结构中。

我已经在iOS 12及以下版本上测试了以下代码,并且它可以正常工作。但是,在iOS 13上我无法展示这个视图控制器。我在viewDidLoad打印了一下输出,它已经被打印出来了,但是视图并没有出现。

func presentInWindow(animated flag: Bool = true, completion: (() -> Void)? = nil) {

        DispatchQueue.main.async {
            var alertWindow: UIWindow?
            alertWindow = UIWindow(frame: UIScreen.main.bounds)
            alertWindow?.windowLevel = UIWindow.Level.alert + 1
            alertWindow?.rootViewController = UIApplication.topViewController()
            if let rootViewController = alertWindow?.rootViewController {
                alertWindow?.makeKeyAndVisible()
                rootViewController.present(self, animated: flag, completion: completion)
            }
        }

}

static func topViewController() -> UIViewController? {

        var topViewController: UIViewController?

        if #available(iOS 13.0, *) {

            topViewController = shared.connectedScenes
                .filter({$0.activationState == .foregroundActive})
                .map({$0 as? UIWindowScene})
                .compactMap({$0})
                .first?.windows
                .filter({$0.isKeyWindow}).first?.rootViewController
        } else {
            topViewController = shared.delegate?.window??.rootViewController
        }

        while true {
            if let presented = topViewController?.presentedViewController {
                topViewController = presented
            } else if let nav = topViewController as? UINavigationController {
                topViewController = nav.visibleViewController
            } else {
                break
            }
        }

        return topViewController
}

这是解决方案:https://dev59.com/-7bna4cB1Zd3GeqPkPmt - Rushabh Shah
1
我的问题出在这一行代码上:'rootViewController.present(self, animated: flag, completion: completion)',当我尝试展示视图控制器时,会出现错误:“[Window] Manually adding the rootViewController's view to the view hierarchy is no longer supported. Please allow UIWindow to add the rootViewController's view to the view hierarchy itself”。 - Karthik
4个回答

1
这段代码可以创建一个视图控制器,你可以在这一行中调整视图控制器的大小:popOverVC.view.frame = lSs。我不确定这段代码是否完全符合你的要求,但如果你需要快速解决问题,它可以在Swift 5、iOS 13和Xcode 11中呈现视图控制器。请注意,它是一个子视图控制器,因此如果你删除父视图控制器,它也会被删除。只需将self更改为你想要呈现的ViewController即可。
    let popOverVC = UIStoryboard(name: "yourSB", bundle: nil).instantiateViewController(withIdentifier: "vcYouWantID") as! vcYouWant
    self.addChild(popOverVC)
    let lSs = UIScreen.main.bounds
    popOverVC.view.frame = lSs
    popOverVC.view.tag = tag
    self.view.addSubview(popOverVC.view)
    popOverVC.didMove(toParent: self)

不,它没有起作用,仍然出现相同的错误:“[Window]手动将rootViewController的视图添加到视图层次结构中不再受支持。请允许UIWindow自己将rootViewController的视图添加到视图层次结构中”在iOS13中。 - Karthik
我直接从一个iOS 13 Swift 5应用程序中复制了代码。我不确定为什么你会遇到错误。 - ekrenzin

0

今晚我遇到了同样的问题。我尝试了网上人们提出的方法,包括Stackoverflow,但都没有起作用。

就在刚才,仿佛魔法般地,我尝试从Main.storyboard中的ViewController(在视觉上是所有子视图的“背景”层)形成一个出口,连接到ViewController.swift中的ViewConstroller类。它在我的iOS 13模拟器项目中的Xcode 12.2中运行良好。

希望这个技巧也能对你有用。


0
我在更新一个之前正常运行的应用程序时遇到了相同的错误。看起来AppDelegate.swift的新要求是:
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    return true
  }

  // MARK: UISceneSession Lifecycle
  func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
  }
  func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) { }
}

hth


-4
我发现这个可以解决我的问题(在旧的Objective-C代码中):
// old way broken in iOS 13
//appDelegate.window.rootViewController = vc;

// this works in iOS 13
[appDelegate.window setRootViewController:vc];

2
你确定这样修复了吗?它应该具有完全相同的效果。 - Iulian Onofrei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接