【问题标题】:Popovers cannot be presented from a view which does not have a window无法从没有窗口的视图中显示弹出框
【发布时间】:2011-03-23 13:31:53
【问题描述】:

这个错误说明了什么:

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

【问题讨论】:

  • 这个错误也发生了,当它被传递 nil 到 optionsButton in [optionsPopoverController presentPopoverFromBarButtonItem:optionsButton allowedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

标签: ipad uipopovercontroller


【解决方案1】:

我遇到了这个问题。

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

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

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

为了解决这个问题,我只为可见视图控制器设置了 leftBarButtonItem,并且每次用户切换标签时都将 barButtonItem 切换到可见视图控制器。

【讨论】:

  • 谢谢!这有助于我找出我的问题。如果其他人正在阅读,只需从另一个 viewController 中删除 barButtonItem,然后再将其设置为当前 viewController。那应该可以。
【解决方案2】:

救了我一命的东西:

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 条件是必要的。

【讨论】:

  • 这个解决方案并不是真正的解决方案。它只能防止症状发生。您需要检查 self.view 何时分配给窗口,然后显示弹出窗口。
  • 其实就是解决方案。无论如何,if 条件始终为真。
  • 这并不总是正确的,因为我已经通过这样的代码进行了调试。如果您认为 if 始终为真,那么为什么要有代码? (欺骗加载视图?)
  • 实际上,这对我也有用...我很迷茫,以至于尝试了该解决方案,它挽救了我的一天。如果您对其进行测试,则条件始终为真,但如果您不测试,则不是。 !!!我相信写“self.view.window”只是调用“moveToWindow”之类的方法。
  • 这实际上是上述问题的真正答案。它应该被标记为正确的。
【解决方案3】:

我换了

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

[actionSheet showInView:self.view];

【讨论】:

    【解决方案4】:

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

    [popoverController.contentViewController.view addSubview:mySubView];
    

    【讨论】:

      【解决方案5】:

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

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

      我的presentPopoverFromRect 调用在我的methodThatDisplaysPopOver 函数中。

      您可以像 MobiMaciek 建议的那样保护每个 presentPopover 调用。

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

      但是,我认为最好了解 self.view.window 何时被分配,并确保在视图有窗口后呈现弹出窗口。

      【讨论】:

        【解决方案6】:

        我遇到了同样的问题,在 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 之后调用..

        【讨论】:

          【解决方案7】:

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

           [self.view addSubview:displayPopOverVC];
          

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

          【讨论】:

            【解决方案8】:

            我遇到了这样的问题。当单击自定义的UIBarButton 项目时收到此消息,该项目使用 did performSeque 调用选择器方法。

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

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

            【讨论】:

              【解决方案9】:

              我收到了与 OP 相同的错误消息,情况与 TPoschel 报告的情况非常相似,只是我有一个拆分视图控制器,在详细信息窗格中有一个嵌入的选项卡栏控制器,以及一个导航控制器。栏按钮项添加为导航栏 leftBarButtonItem。

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

              如果我不这样做,通过调试我自己的代码,栏按钮项的 window 属性保持设置为 nil,并在 返回 到您想要的屏幕时导致异常以前去过。我猜是在导航项中设置 leftBarButtonItem 的副作用,它会熄灭并设置框架。但它似乎并不麻烦,除非按钮与当前设置的按钮不同。因此,离开选项卡时需要将其设置为 nil,即使从技术上讲,它与传递的按钮相同。

              我会赞成 TPoschel 的回答,除非我不允许。

              【讨论】:

                【解决方案10】:

                inView的时候也会出现这个错误:Parameter is wrong - to test try self.view

                【讨论】:

                  【解决方案11】:

                  在将相同的UIBarButtonItem 分配给多个导航项时,我收到了与 Lewis 相同的错误消息。我的示例稍微复杂一些,因为我使用的是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;
                  } 
                  

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

                  【讨论】:

                    【解决方案12】:

                    刚遇到这个问题。原来 inView: 参数正在使用未在 IB 中连接的 IBOutlet。因此,尝试在 nil 中启动弹出框。这行不通。

                    所以,请确保您使用的是有效视图。

                    【讨论】:

                    • 同样,我在存在视图的视图控制器中将 inView 设置为 self.mySpecialView。然后我将该视图控制器的类子类化以在 mySpecialView 不存在的视图控制器中使用并收到此错误。
                    【解决方案13】:

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

                    试着等到

                    - (void) didMoveToWindow
                    

                    为视图调用,然后加载弹出框

                    【讨论】:

                    • 你能解释一下吗?我不明白。
                    • 只需将 [popoverController presentPopoverFromRect... 放在 didMoveToWindow 或 viewDidAppear 函数中。它在 viewDidLoad 之后调用
                    • UIBarButtonItem 怎么样?
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-05-09
                    • 1970-01-01
                    • 2013-01-06
                    • 1970-01-01
                    • 2019-11-15
                    相关资源
                    最近更新 更多