Предупреждение: попытка представить * on*, чье представление не находится в иерархии окон-swift
Я пытаюсь представить 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)
}
}
Я пробовал различные решения, найденные с помощью Google без успеха.
12 ответов:
на этом этапе в вашем коде представление контроллера вида было только создано, но не добавлено ни в какую иерархию представлений. Если вы хотите представить из этого контроллера вида как можно скорее, вы должны сделать это в
viewDidAppearбезопасность.
в объективе c: Это решает мою проблему, представляя файле ViewController сверху спасибо за статью
- (UIViewController*) topMostController { UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topController.presentedViewController) { topController = topController.presentedViewController; } return topController; }
Swift 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просто отрегулируйте контроллер вида, если вам нужно переключаться между несколькими экранами раскадровки.
Swift 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) } func presentExampleController() { let exampleStoryboard = UIStoryboard(named: "example", bundle: nil) let exampleVC = storyboard.instantiateViewController(withIdentifier: "ExampleVC") as! ExampleVC present(exampleVC, animated: true) }
быстро
func topMostController() -> UIViewController { var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController! while (topController.presentedViewController != nil) { topController = topController.presentedViewController! } return topController }
Swift 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}
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: 0x7fdd01703990 на myapp.testController: 0x7fdd01703690 чей вид не находится в иерархии окон!
надеюсь, что это поможет другим с swift 3
Я пробовал так много подходов! единственная полезная вещь:
if var topController = UIApplication.shared.keyWindow?.rootViewController { while (topController.presentedViewController != nil) { topController = topController.presentedViewController! } }
все реализации для topViewController здесь не полностью поддерживают случаи, когда у вас есть
UINavigationControllerилиUITabBarController, для этих двух вам нужна немного другая обработка:на
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, хотя другие кажутся правильными, но более хакерскими
другой стиль презентации можно найти на apple doc
Comments