无法从没有窗口的视图中呈现弹出窗口

时间:2010-07-31 05:50:26

标签: ipad uipopovercontroller

此错误表示:

"Popovers cannot be presented from a view which does not have a window."

13 个答案:

答案 0 :(得分:30)

拯救我生命的东西:

if (self.view.window != nil)
    [popoverController presentPopoverFromRect:CGRectMake(44, yCoord, 111, 111) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

通过添加if条件它不再崩溃。我真的不明白,因为presentPopoverFromRect函数总是被调用。没有窗口会是零的情况,但无论如何它都可以解决问题。

编辑:我在viewDidAppear中有此代码。 然而,在大多数情况下,将presentPopoverFromRect移动到viewDidAppeardidMoveToWindow就足够了,但在我的情况下,由于某种原因,if条件是必要的。

答案 1 :(得分:24)

您要添加popover的视图必须已经使用“addSubview:”方法添加到窗口中。

请等到

- (void) didMoveToWindow
为视图调用

,然后加载popover

答案 2 :(得分:4)

我遇到了这个问题。

我有一个UITabBarController作为详细视图,我在选项卡栏中的所有三个导航控制器上将barButtonItem设置为leftBarButtonItem。

vcChart.navigationItem.leftBarButtonItem = barButtonItem;
vcAnalysis.navigationItem.leftBarButtonItem = barButtonItem;
vcTechnicals.navigationItem.leftBarButtonItem = barButtonItem;

原来只有最后一个添加有效,前两个会在点击时抛出异常。

要修复它,我只为可见视图控制器设置leftBarButtonItem,并且每次用户切换标签时,只将barButtonItem切换到可见视图控制器。

答案 3 :(得分:2)

刚遇到这个问题。原来,inView:参数使用的是IB未连接的IBOutlet。因此,试图以零开始使用popover。这不起作用。

因此,请确保您使用的是有效视图。

答案 4 :(得分:2)

有很多方法可以解决此错误。基本上,您需要等待调用presentPopover命令,直到将调用视图添加到窗口。我是这样做的。

- (void)viewDidAppear:(BOOL)animated
{
    [self methodThatDisplaysPopOver];
}

我的presentPopoverFromRect电话位于我的methodThatDisplaysPopOver功能中。

你可以像MobiMaciek建议的那样保护每一个当前的过去调用。

if (self.view.window != nil)
    [popoverController presentPopoverFromRect:CGRectMake(10, 10, 100, 100) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

但是,我认为最好先了解一下self.view.window的分配情况,并确保在视图有窗口后向您显示popover。

答案 5 :(得分:1)

我和Lewis一样,为多个导航项目分配了相同的UIBarButtonItem时收到了同样的错误消息。当我使用UISplitViewController时,我的例子稍微复杂一些。

在我的RootViewController中,我有一个数组数组来完成表格中的多个部分。每次用户单击表中的行时,都会在splitViewController的右窗格中放置一个新的“详细信息”视图控制器。在设置leftBarButtonItem = nil之前,我会在点击“菜单”按钮3-4次后收到一个段错误,其错误与a111相同。我更新了我的代码以实际检索先前的详细视图控制器并将leftBarButtonItem项设置为nil。

allData是我的NSMutableArray,它包含几个其他NSMutableArrays作为对象。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Retrieve the new detail view controller
    UIViewController *detailViewController = [[self.allData objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];

    // Add the detail view controller to a navigation controller and set the bar style
    UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
    detailNavigationController.navigationBar.barStyle = [[NSUserDefaults standardUserDefaults] integerForKey:@"UIBarStyle"];

    // Retrieve previous detail view controller and remove the leftBarButtonItem
    UINavigationController *previousDetailNavigationController = [splitViewController.viewControllers objectAtIndex:1];
    UIViewController *previousDetailViewController = [[previousDetailNavigationController viewControllers] lastObject];
    previousDetailViewController.navigationItem.leftBarButtonItem = nil;

    // Update the split view controller's view controllers array.
    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailNavigationController, nil];
    splitViewController.viewControllers = viewControllers;

    [detailNavigationController release];
    [viewControllers release];

    // Dismiss the popover if it's present.
    if (popoverController != nil) {
        [popoverController dismissPopoverAnimated:YES];
    }

    // This sets the left bar to nil when in landscape and equal to "Menu" when in portrait.
    // We need to remove rootPopoverButtonItem from the previous viewController...
    detailViewController.navigationItem.leftBarButtonItem = rootPopoverButtonItem;
} 

错误信息起初有点欺骗,但上面的答案帮助了我。我想知道为什么我可以在segfault之前点击“菜单”按钮最多3-4次......我会进一步调查。

答案 6 :(得分:1)

当inView:参数不正确时,也会发生此错误 - 要测试try self.view

答案 7 :(得分:1)

是的,你是对的,但我们仍然可以从父类中添加子视图。所以它可以从一个有窗口的视图中表示:

[popoverController.contentViewController.view addSubview:mySubView];

答案 8 :(得分:0)

我有与OP相同的错误信息,与TPoschel报告的情况非常相似,除了我在详细信息窗格中有一个带有嵌入式标签栏控制器的拆分视图控制器,以及其中的导航控制器。条形按钮项目添加为导航栏leftBarButtonItem。

仅在iOS5.0(不是5.1)上,它似乎要求您通过将其设置为nil而使您要离开的标签栏上的条形按钮项无效。在此之前,将栏按钮添加到您要去的选项卡上的导航栏。

如果我不这样做,从调试我自己的代码,bar按钮项的window属性保持设置为nil,并导致异常,返回到你的屏幕以前去过。我猜测是在导航项中设置leftBarButtonItem的副作用,它会关闭并设置框架。但除非按钮与当前设置的按钮不同,否则它似乎不会打扰。因此,在离开标签时需要将其设置为nil,即使它在技术上与传递的按钮相同。

我会赞成TPoschel的答案,除非SO不会让我。

答案 9 :(得分:0)

我有这样的问题。单击调用performSeque的选择器方法的自定义UIBarButton项时收到此消息。

问题是我的segue仍然附加到UIBarButton项目。它应该附加到视图控制器的主视图。改变了这一点并且工作正常。

P.S。,这一切都已经开始,因为我想在我的UIToolBar添加“info”按钮。这不是系统提供的列表中的一个,应该是。

答案 10 :(得分:0)

将会有一个视图,您要求显示您的弹出窗口。出现此错误的原因是您没有将此视图作为窗口的子视图。

 [self.view addSubview:displayPopOverVC];

其中displayPopOverVC是popOver出现的视图控制器

答案 11 :(得分:0)

我遇到同样的问题,在 viewDidAppear 中添加 PresentPopOver 后,这已经解决了

- (void) viewDidAppear:(BOOL)animated{
     CGRect popoverRect = screenBounds;         
     popoverRect.size.width = MIN(popoverRect.size.width,0) ;
     popoverRect.origin.x  = screenBounds.origin.x;

     [popoverController
     presentPopoverFromRect:popoverRect
     inView:self.view
     permittedArrowDirections:UIPopoverArrowDirectionAny
     animated:YES];
}

这发生在inView中:self.view应该在@ hey68You和MobiMaciek建议的viewDidLoad之后调用..

答案 12 :(得分:0)

我替换了

[actionSheet showFromBarButtonItem:self.navigationController.navigationItem.leftBarButtonItem animated:YES];

[actionSheet showInView:self.view];