窗口层次结构问题中,哪个视图不在层次结构中?

5

警告:尝试在未在窗口层次结构中的视图上呈现。

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

- (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 选项。谢谢!


当调用PostToFacebook窗口时,屏幕上没有显示任何内容。只有我从中调用的屏幕。但是UActionSheet可以工作,然后我点击Post to Facebook,就会出现警告,UIActionSheet消失了,然后回到我从中调用它的屏幕。 - Jason
presentViewController:animated:completion: 需要从当前屏幕上呈现的 viewController 中调用。如果 SocialHelper 不是当前呈现的 viewController,则不应在其上调用此方法。 - Paul.s
我尝试将所有内容移动到正在显示的UIViewController类中,但仍然收到相同的警告。 - Jason
请分享您的项目;可能视图层次结构会很混乱,但是如果不看到视图层次结构是如何构建的,甚至猜测问题出在哪里都非常困难... - holex
你需要分解问题。我曾经遇到过这样的问题,花了一整天才发现我漏掉了'super'调用。尝试呈现简单的视图控制器 [self presentViewController:[UIViewController new] animated:YES completion:nil]; - Saqib Saud
显示剩余6条评论
2个回答

12

我会更改传递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”呈现:

修改:由于前两个建议对您的项目没有起作用,请尝试从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 是什么。尝试了当前答案中的两个选项,但都没有起作用。 - Jason
这是我的代码...MainViewController带有UINavigationController,它有一个用于设置的FlipsideViewController,然后有一个“关于”页面的按钮,该页面也是一个UIViewController。我在关于页面添加了日志,在那里调用了UIActionSheet(显示UINavigation是当前的ViewController)。UIActionSheet的方法在socialhelper类中,该类是NSObject。我尝试将所有内容移动到About UIViewController类中...但结果相同。希望这可以帮助到您。 - Jason
尝试了你的topViewController,没有任何反应。没有错误或崩溃,就是什么都没有发生。 - Jason

1

这个答案可能无法解决您的问题,但它应该能够让您理解为什么它不起作用,并帮助您找到最初想要的正确解决方案。

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

正如在这行代码中正确执行的那样,但是,self 需要是一个 UIViewController(具有视图属性的对象)。

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

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

来自苹果公司的UIViewController参考页面

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

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

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

如果只需要在两到三个视图控制器中显示操作表,我会复制代码而不是创建单独的类;如果有多个视图控制器,则将操作表显示逻辑作为单独的类是有意义的,您只需要找到合适的设计模式来实现。

编辑 1

忘记提及您变量声明时缺少 SLComposeViewController * 了。

它只是在您的帖子中缺失还是您已经在 viewcontroller 类中的其他地方声明了该变量?

尝试在创建 SLComposeViewController 的同一行中声明它,这可能会解决问题。 如果这样做不起作用,请通过查看这个 简单易懂的教程 来双重检查您在应用程序中支持 Facebook 所需完成的所有操作。

SLComposeViewController *slComposeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];

我假设您已经创建了带有主视图控制器作为其根视图的导航控制器:

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

为了显示翻转控制器,您需要在主视图控制器中执行以下操作:

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

翻转侧面控制器有关于按钮,当点击时会显示关于视图;我认为你应该使用presentViewController而不是push:
[self presentViewController:aboutViewController animated:YES];

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

这是我所拥有的……一个带有UINavigationController的MainViewController,它还有一个用于设置的FlipsideViewController,然后是一个名为"about"的页面按钮,它也是一个UIViewController。我在关于页面添加了日志,其中UIActionSheet从中调用(显示UINavigation是当前ViewController)。UIActionSheet的方法位于socialhelper类中,该类是NSObject。我已尝试将所有内容移至About UIViewController类中……但结果相同。希望这可以帮助到您。 - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接