【问题标题】:Whose view is not in the window hierarchy issue?谁的视图不在窗口层次问题中?
【发布时间】:2014-07-21 04:38:22
【问题描述】:

警告:尝试呈现不在窗口层次结构中的视图!

是的,在发布此问题之前,我已经查看了其他问题和答案。他们没有帮助我解决这个问题。这就是我正在做的事情。我正在调用我的单例类 socialHelper 来显示一个操作表,其中 postToFacebook 方法是一个可供选择的选项。单击此操作时,我收到上面的警告,并且不显示 postToFacebook。我从 UIViewController 中调用它,UINavigationController 作为主控制器,我的 SocialHelper 类是 NSOject

- (void)postToFacebook
{
    if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {

    slComposeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
    [slComposeViewController setInitialText:@"Building stairs? Checkout StairsPro on the app store!"];
    [slComposeViewController addImage:[UIImage imageNamed:@"StairsIcon120x120.png"]];
    [slComposeViewController addURL:[NSURL URLWithString:@"https://itunes.apple.com/us/app/stairs-pro/id477032819?ls=1&mt=8"]];

    [self presentViewController:slComposeViewController animated:YES completion:nil];

    // I've also tried this, which shows the post window, but after hitting cancel or post, my previous viewController is not the current viewController. So my navigation bar is gone and can't move around in my app. 
    // [[[[UIApplication sharedApplication]delegate]window]setRootViewController:slComposeViewController];

    }else{
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"No Facebook Account" message:@"No Facebook account has been configured. You can configure or create a Facebook account in settings." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
        [alert show];
}
}

所以我要问的是在这种情况下让slComposerViewController 显示的最佳方式是什么,以及我们如何使用UIApplication 选项。谢谢!

【问题讨论】:

  • SocialHelper 真的在屏幕上吗?
  • 当它被调用到 PostToFacebook 窗口时,屏幕上什么也没有显示。只是我调用它的屏幕。但是 UActionSheet 有效,然后我点击 Post to Facebook,我收到警告,UIActionSheet 消失,然后回到我调用它的屏幕。
  • presentViewController:animated:completion: 需要从当前显示在屏幕上的 viewController 调用。如果SocialHelper 不是当前呈现的viewController,那么你不应该在它上面调用这个方法
  • 我尝试将所有内容移动到正在显示的 UIViewController 类并得到相同的警告。
  • 你确定你有正确的viewController吗?

标签: ios uiviewcontroller hierarchy


【解决方案1】:

我会更改传递 ViewController 的方法,以确保正确的 VC 像这样呈现它:

- (void)postToFacebookFromVC:(UIViewController*) presentingVC

在调用 presentViewController 时在该方法内部使用:

[presentingVC presentViewController:slComposeViewController animated:YES completion:nil];

我假设使用你的 socialHelper 单例类会是这样的:

[[socialHelper sharedResource] postToFacebookFromVC:self]; //inside the VC that you want to display it

关于使用 rootViewController 的第二个问题试试这个:

[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:slComposeViewController animated:YES completion:nil];

编辑:由于前两个建议不适用于您的项目,请尝试获取 topMost ViewController 并从中呈现 slComposeViewController 而不是像这样的“self”:

UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (topController.presentedViewController) {
    topController = topController.presentedViewController;
}

[topController presentViewController:slComposeViewController animated:YES completion:nil];

【讨论】:

  • UINavigationController 是呈现视图。我运行了一个 NSLog 来查看当前的 viewController 是什么。在当前答案中尝试了这两个选项,但都没有成功。
  • 这就是我所拥有的...MainViewController 和 UINavigationController,它是用于设置的 FlipsideViewController,然后是“关于”页面的按钮,它也是一个 UIViewController。我在关于从中调用 UIActionSheet 的位置添加了日志(显示 UINavigation 是当前的 ViewController)。 UIActionSheet 的方法位于 NSObject 的 socialhelper 类中。我已经尝试将所有内容移至 About UIViewController 类......这给出了相同的结果。希望这会有所帮助
  • 试过你的topViewController,什么也没做。没有错误或崩溃,什么都没有。
【解决方案2】:

此答案不会解决您的问题,但它应该能够理解为什么它不起作用,并帮助您找到适合您最初意图的正确解决方案。

SLComposeViewController 是一个UIViewController 有一个关联的UIView,它将显示在接收消息presentViewController 的控制器的视图顶部。

正如在这一行中所做的那样,self 必须是 UIViewController(具有视图属性的对象)。

[self presentViewController:slComposeViewController animated:YES completion:nil];

如果您将-postToFaceBook 方法移出SocialHelper 类并将其放入将显示操作表的UIViewController 类(文件)中,它将起作用,这样self 实际上是一个@ 987654334@ 而不是 NSObject

来自苹果的UIViewController reference page

当你在 UIViewController 上调用 presentViewController 方法时 它将presentedViewController 属性设置为指定的视图 控制器,调整该视图控制器的视图大小,然后添加 视图到视图层次结构。

您的 SocialHelper 类不是视图控制器,因此它没有可以添加操作表视图以显示它的视图(在顶部)。

我在想,即使你从UIViewController 继承你的SocialHelper,你的SocialHelper 的视图也不会在你的控制器的视图层次结构中。

如果只有两个或三个视图控制器需要显示操作表,我会复制代码而不是创建单独的类;如果是多个视图控制器,那么将操作表显示逻辑作为一个单独的类是有意义的,您只需要找到正确的设计模式即可。

编辑 1

忘记提及你的变量声明缺少SLComposeViewController *

它只是在您的帖子中丢失,还是您在视图控制器类的其他地方声明了变量?

尝试在您创建 SLComposeViewController 的同一行中声明它;这可能会解决问题。如果这不起作用,请查看simple and easy to follow tutorial,仔细检查您在应用中支持 Facebook 所需要做的一切。

SLComposeViewController *slComposeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];

我假设您以主视图控制器为根创建了导航控制器:

navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];

要在主视图控制器中显示反面控制器:

[[self navigationController] pushViewController:flipSideViewController animated:NO];

反面控制器有关于按钮,点击时显示关于视图;我在想你做的是 presentViewController 而不是推送:

[self presentViewController:aboutViewController animated:YES];

最后,在 about 视图控制器中,您应该拥有带有上述更正行的 -postToFacebook 方法;这将被日志调用(按钮?)。

【讨论】:

  • 这就是我所拥有的...MainViewController 和 UINavigationController,它是用于设置的 FlipsideViewController,然后是“关于”页面的按钮,它也是一个 UIViewController。我在关于从中调用 UIActionSheet 的位置添加了日志(显示 UINavigation 是当前的 ViewController)。 UIActionSheet 的方法位于 NSObject 的 socialhelper 类中。我已经尝试将所有内容移至 About UIViewController 类......这给出了相同的结果。希望这会有所帮助
猜你喜欢
  • 2012-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多