谁的视图不在窗口层次结构问题中?

时间:2014-05-31 14:29:41

标签: ios uiviewcontroller hierarchy

  

警告:尝试显示其视图不在窗口层次结构中!

是的,在发布此问题之前,我已查看过其他问题和答案。他们没有帮我解决这个问题。这就是我在做什么。我正在调用我的单例类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选项。谢谢!

2 个答案:

答案 0 :(得分: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”,如下所示:

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

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

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

答案 1 :(得分:1)

这个答案不会解决您的问题,但应该弄清楚它为什么不起作用,并帮助您找到最初预期的正确解决方案。

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

正如在此行中正确完成的那样,self必须是UIViewController(具有视图属性的对象)。

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

如果您将-postToFaceBook方法移出SocialHelper类并将其放在将显示操作表的UIViewController类(文件)中,它将会起作用,这样{ {1}}实际上是self而不是UIViewController

来自Apple的UIViewController reference page

  

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

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

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

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

修改1

忘记提及您的变量声明缺少SocialHelper

你的帖子中是否缺少它,或者你在viewcontroller类的其他地方声明了变量?

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

SLComposeViewController

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

SLComposeViewController *slComposeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];

要显示翻转侧控制器,请在主视图控制器中执行此操作:

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

翻转侧控制器有一个约按钮,用于在敲击时显示关于视图;我在想你做一个presentViewController而不是推送:

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

最后,在about视图控制器中,您应该使用上面提到的更正行的-postToFacebook方法;这将由日志调用(按钮?)。