Actuellement, j'utiliser cette méthode pour obtenir le contrôleur de vue actuel:fil de manière sûre pour obtenir contrôleur de vue affichée
func topMostContoller()-> UIViewController?{
if !Thread.current.isMainThread{
logError(message: "ACCESSING TOP MOST CONTROLLER OUTSIDE OF MAIN THREAD")
return nil
}
let topMostVC:UIViewController = UIApplication.shared.keyWindow!.rootViewController!
return topVCWithRootVC(topMostVC)
}
Cette méthode passe par la hiérarchie des contrôleurs de vue à partir de la RootViewController jusqu'à ce qu'il atteigne le sommet .
func topVCWithRootVC(_ rootVC:UIViewController)->UIViewController?{
if rootVC is UITabBarController{
let tabBarController:UITabBarController = rootVC as! UITabBarController
if let selectVC = tabBarController.selectedViewController{
return topVCWithRootVC(selectVC)
}else{
return nil
}
}else if rootVC.presentedViewController != nil{
if let presentedViewController = rootVC.presentedViewController! as UIViewController!{
return topVCWithRootVC(presentedViewController)
}else{
return nil
}
} else {
return rootVC
}
}
Cette question est en topMostController
car il utilise UIApplication.shared.keyWindow
et UIApplication.shared.keyWindow.rootViewController
qui ne devrait pas être utilisé dans un thread d'arrière-plan. Et je reçois ces avertissements:
runtime: UI API called from background thread: UIWindow.rootViewController must be used from main thread only
runtime: UI API called from background thread: UIApplication.keyWindow must be used from main thread only
Alors ma question est. Y a-t-il un moyen sûr d'accéder au contrôleur de vue actuellement affiché?
Ajouter '' retour nil' juste après 'logError ...'. Mais la bonne solution consiste à corriger votre code de sorte que vous n'appelez 'topMostController' que depuis la file d'attente principale. – rmaddy