Я пытаюсь представить, есть ViewController
ли какие-либо сохраненные данные в модели данных. Но я получаю следующую ошибку:
Предупреждение: Попытка представить * на *, чей вид не входит в иерархию окон "
Соответствующий код:
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.
ios
swift
hierarchy
presentviewcontroller
Нильс Васелл
источник
источник
ViewController
в Storyboard? Я не используюNavigationController
@derdidaUIViewController
части). @derdidaОтветы:
На данный момент в вашем коде представление контроллера представления только создано, но не добавлено ни в какую иерархию представлений. Если вы хотите сделать презентацию из этого контроллера представления как можно скорее, сделайте это
viewDidAppear
как можно безопаснее.источник
В объекте c: это решило мою проблему при представлении контроллера просмотра поверх mpmovieplayer
- (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
Просто настройте контроллер представления, если вам нужно переключаться между несколькими экранами раскадровки.
источник
Свифт 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)
источник
для SWIFT
func topMostController() -> UIViewController { var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController! while (topController.presentedViewController != nil) { topController = topController.presentedViewController! } return topController }
источник
topController
эта функция возвращает тот же самый VC, что иself
при попытке представления напрямую с использованиемself.presentViewController(myModalVC)
, но при передаче представляющего VC с использованием вашей функции ошибки иерархии представлений не возникает.Просто нужно выполнить селектор с задержкой - (работает 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 4
func topMostController() -> UIViewController { var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController! while (topController.presentedViewController != nil) { topController = topController.presentedViewController! } return topController }
источник
public static func getTopViewController() -> UIViewController?{ if var topController = UIApplication.shared.keyWindow?.rootViewController { while (topController.presentedViewController != nil) { topController = topController.presentedViewController! } return topController } return nil}
источник
Я получал эту ошибку, когда представлял контроллер после того, как пользователь открыл deeplink. Я знаю, что это не лучшее решение, но если у вас короткие сроки, вот быстрое решение - просто оберните свой код в
asyncAfter
:DispatchQueue.main.asyncAfter(deadline: .now() + 0.7, execute: { [weak self] in navigationController.present(signInCoordinator.baseController, animated: animated, completion: completion) })
Это даст время для звонка вашему представляющему контроллеру
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)
Казалось, это сработало, чтобы убедиться, что это самый верхний вид.
Я получал ошибку
Надеюсь, это поможет другим с быстрым 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 } }
источник
Предыдущие ответы относятся к ситуации, когда контроллер представления, который должен представлять представление 1) еще не добавлен в иерархию представлений, или 2) не является контроллером представления сверху.
Другая возможность заключается в том, что предупреждение должно быть представлено, когда другое предупреждение уже представлено, но еще не закрыто.
источник
Swift Method и предоставьте демонстрацию.
func topMostController() -> UIViewController { var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController! while (topController.presentedViewController != nil) { topController = topController.presentedViewController! } return topController } func demo() { let vc = ViewController() let nav = UINavigationController.init(rootViewController: vc) topMostController().present(nav, animated: true, completion: nil) }
источник
Swift 5.1 :
let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main) let mainViewController = storyboard.instantiateViewController(withIdentifier: "ID") let appDeleg = UIApplication.shared.delegate as! AppDelegate let root = appDeleg.window?.rootViewController as! UINavigationController root.pushViewController(mainViewController, animated: true)
источник
У меня сработало использование основного потока для представления и отключения контроллера представления.
DispatchQueue.main.async { self.present(viewController, animated: true, completion: nil) }
источник
Вместо поиска контроллера вида сверху можно использовать
viewController.modalPresentationStyle = UIModalPresentationStyle.currentContext
Где viewController - это контроллер, который вы хотите представить. Это полезно, когда есть разные виды представлений в иерархии, такие как TabBar, NavBar, хотя другие кажутся правильными, но более хакерскими
Другой стиль презентации можно найти в документе Apple.
источник