Предупреждение: попытайтесь представить * на *, чей вид не находится в иерархии окон - быстро
Я пытаюсь представить 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, но безуспешно.
Ответы
Ответ 1
В этот момент вашего кода представление контроллера просмотра было создано, но не добавлено ни в одну иерархию представлений. Если вы хотите как можно скорее представить этот контроллер, вы должны сделать это в viewDidAppear
для обеспечения безопасности.
Ответ 2
В объекте c:
Это решило мою проблему при представлении viewcontroller поверх mpmovieplayer
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
Ответ 3
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
Просто перейдите к контроллеру представления, если вам нужно переключаться между несколькими экранами раскадровки.
Ответ 4
Вам просто нужно выполнить селектор с задержкой - (работает 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)
}
Ответ 5
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)
Ответ 6
для SWIFT
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
Ответ 7
Swift 4
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
Ответ 8
Для быстрого 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}
Ответ 9
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, чей вид не находится в иерархии окон!
Надеюсь, что это поможет другим с быстрым 3
Ответ 10
Я пробовал так много утверждений! единственная полезная вещь:
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
}
Ответ 11
Вся реализация для 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
}
}
Ответ 12
Я получал эту ошибку, когда представлял контроллер после того, как пользователь открыл ссылку. Я знаю, что это не лучшее решение, но если вы находитесь в сжатые сроки, вот быстрое решение - просто оберните ваш код в asyncAfter
:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.7, execute: { [weak self] in
navigationController.present(signInCoordinator.baseController, animated: animated, completion: completion)
})
Это даст вашему представителю время для вызова viewDidAppear
.
Ответ 13
Вместо того, чтобы находить контроллер верхнего уровня, можно использовать
viewController.modalPresentationStyle = UIModalPresentationStyle.currentContext
Где viewController - это контроллер, который вы хотите представить
Это полезно, когда в иерархии, например TabBar, NavBar, есть разные виды представлений, хотя другие кажется правильными, но более хакерскими
Другой стиль презентации можно найти на apple doc