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

Ios 谁的视图不在窗口层次结构问题中?,ios,uiviewcontroller,hierarchy,Ios,Uiviewcontroller,Hierarchy,警告:尝试显示其视图不在窗口层次结构中的对象 是的,在发布此问题之前,我已经查看了其他问题和答案。他们没有帮我解决这个问题。这就是我正在做的。我正在调用我的singleton类socialHelper来显示一个操作表,其中可以选择postToFacebook方法。单击此操作时,我会收到上面的警告,并且不会显示postToFacebook。我从一个UIViewController调用它,主控制器是UINavigationController,而我的SocialHelper类是一个NSOject -

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

是的,在发布此问题之前,我已经查看了其他问题和答案。他们没有帮我解决这个问题。这就是我正在做的。我正在调用我的singleton类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];
}
}

因此,我要问的是,在这种情况下,让
slcomposereviewcontroller
显示的最佳方法是什么,以及如何使用
UIApplication
选项。谢谢大家!

我会将方法更改为传入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];
编辑:由于前两个建议不适用于您的项目,请尝试获取最顶部的ViewController,并从中呈现slComposeViewController,而不是像这样的“自我”:


这个答案不会解决你的问题,但它应该能解释为什么它不起作用,并帮助你找到正确的解决方案

SLComposeViewController
作为
UIViewController
具有关联的
UIView
,该视图将显示在接收消息的控制器视图顶部
presentViewController

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

如果您将
-postToFaceBook
方法移出
SocialHelper
类,并将其放入将显示操作表的
UIViewController
类(文件)中,则该方法将起作用,这样
self
实际上是
UIViewController
而不是
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];
}
}
来自苹果的:

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

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

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

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

编辑1

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

是您的帖子中缺少该变量,还是您在viewcontroller类的其他地方声明了该变量

尝试在创建
SLComposeViewController
的同一行中声明它;这可能会解决问题。如果这不起作用,那么仔细检查一下你的应用程序中支持Facebook所需要做的一切

我假设您创建了导航控制器,并将主视图控制器作为其根:

navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
要显示翻转侧控制器,请在主视图控制器中执行以下操作:

[[self navigationController] pushViewController:flipSideViewController animated:NO];
翻转侧控制器具有“关于”按钮,以在点击时显示“关于”视图;我想你做的是presentViewController而不是推送:

[self presentViewController:aboutViewController animated:YES];

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

社交助手是否确实在屏幕上?在PostToFacebook窗口调用时,屏幕上没有显示任何内容。就在屏幕上,我叫它。但是UAActionSheet工作正常,然后我点击Facebook上的Post,我得到警告,UIActionSheet就消失了,回到我调用它的屏幕。
presentViewController:animated:completion:
需要从屏幕上当前显示的viewController调用。如果
SocialHelper
不是当前显示的viewController,则不应在itI上调用此方法。我尝试将所有内容移动到正在显示的UIViewController类,并得到相同的警告。是否确实拥有正确的viewController?UINavigationController是当前显示的视图。我运行了一个NSLog来查看当前的viewController是什么。在当前答案中尝试了这两个选项,但都不起作用。以下是我得到的…带有UINavigationController的MainViewController,它是用于设置的FlipsideViewController,然后是“关于”页面的按钮,也是UIViewController。我在中添加了关于从何处调用UIActionSheet的日志(显示UINavigation是当前的ViewController)。UIActionSheet的方法位于socialhelper类中,该类是NSObject。我尝试过将所有内容移动到About UIViewController类中,得到了相同的结果。希望这有助于您的topViewController,但未执行任何操作。没有错误或崩溃,什么都没有。这是我拥有的…带有UINavigationController的MainViewController,它是一个用于设置的FlipsideViewController,然后是“关于”页面的按钮,也是一个UIViewController。我在关于whe的日志中添加了日志
[[self navigationController] pushViewController:flipSideViewController animated:NO];
[self presentViewController:aboutViewController animated:YES];