iOS:如何解散popovers

时间:2011-12-28 13:13:04

标签: objective-c uipopovercontroller uistoryboard

  

可能重复:
  How to Dismiss a Storyboard Popover

我有一个iPad故事板。一个视图中的条形按钮项目被控制拖动到另一个视图 - 并选择一个弹出框样式。当我按下按钮时,弹出窗口中会显示新的弹出视图,但我有两个问题:

  1. 当我再次按下按钮时,会显示另一个弹出视图实例 - 我可以看到,黑色边框越来越暗。如果弹出窗口打开并按下按钮,则弹出视图应该关闭。我该怎么办?
  2. 目前,即使视图中的内容不是高度,新的弹出视图也会浮动到屏幕的按钮上。如何控制弹出框视图的尺寸?
  3. EDIT1:

    我通过从控制器底部的黄色控制器图标拖动到另一个视图来创建了一个segue,该视图应该位于popover内部。此弹出窗口的标识符为settingsPopover。

    然后我在IBAction中执行此操作:

    - (IBAction)settingsButtonTapped:(id)sender {
            [self performSegueWithIdentifier:@"settingsPopover" sender:self];
    }
    

    但这给了我这个错误:

      

    由于未捕获的异常而终止应用   'NSInternalInconsistencyException',原因:'UIStoryboardPopoverSegue   必须通过条形按钮项或视图显示。'

    我是否以错误的方式或调用performSegueWithIdentifier错误创建了segue?

    EDIT2:

    我创建了这个IBAction:

    - (IBAction)settingsButtonTapped:(id)sender {
        if (_settingsPopover == nil) {
            SettingsViewController* settingsView = [[SettingsViewController alloc] initWithStyle:UITableViewStylePlain];
            self.settingsPopover = [[UIPopoverController alloc] initWithContentViewController:settingsView];
        }
        [self.settingsPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
    

    它几乎可以工作,但一个缺点是它没有使用我的Storyboard中设计的UIView。例如,在我的故事板中,将类SettingsViewController设计为分组表视图的视图。有没有办法在popover中显示故事板中设计的UIView而不是原始的SettingsViewController实例?

    解决方案:

    我在故事板中创建了一个全局segue,标识符为“settingsPopover”。

    - (IBAction)settingsButtonTapped:(id)sender {
        if (self.settingsPopover==nil) {
            [self performSegueWithIdentifier:@"settingsPopover" sender:sender];
        }
    }
    
    #pragma mark - UIView
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {    
        if ([segue.identifier isEqualToString:@"settingsPopover"]) {
            self.settingsPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
            self.settingsPopover.delegate = self;
        }
    }
    
    #pragma mark - UIPopoverControllerDelegate
    - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
        self.settingsPopover = nil;
    }
    

4 个答案:

答案 0 :(得分:2)

  

然后我在IBAction中执行此操作:

- (IBAction)settingsButtonTapped:(id)sender {
        [self performSegueWithIdentifier:@"settingsPopover" sender:self];
}
     

但这给了我这个错误:

     

由于未捕获的异常而终止应用   'NSInternalInconsistencyException',原因:'UIStoryboardPopoverSegue   必须通过条形按钮项或视图显示。'

     

我是以糟糕的方式还是在通话中创建了segue   performSegueWithIdentifier错了吗?

当你拨打self时,你正在传递sender而不是-performSegueWithIdentifier:sender:(点击按钮),即你给segue一个UIViewController所在的地方UIBarButtonItemUIView

这应该有效:

 - (IBAction)settingsButtonTapped:(id)sender {
         [self performSegueWithIdentifier:@"settingsPopover" sender:sender];
 }

答案 1 :(得分:1)

故事板是一种通用的应用流程和界面工具。它们从代码中抽象出许多常见的样板,以便您可以轻松地看到高级别的内容。

不幸的是,您无法在Storyboard中捕获纯粹的逻辑。正如故事板很乐意将视图控制器模态地呈现为segue但没有意识到以模态方式解除视图控制器,故事板将呈现弹出控制器,但它不提供解除它们的能力。

  1. 只需为条形按钮创建自定义IBAction,而不是使用segue。如果是,则跟踪是否出现弹出窗口并将其解除。

  2. UIPopoverController有一个名为popoverContentSize的属性,可让您控制此属性。

答案 2 :(得分:1)

每次执行Segue时,它都会创建一个新的viewController,就像你看到将按钮连接到执行segue时所看到的那样。因此,您需要通过从底部的viewController图标拖动到目标来为viewController创建“通用”segue。然后,当LucasTizma建议将按钮挂钩到IBAction,要么调用performSegueWithIdentifier:要么取消弹出窗口,条件是弹出窗口是否在屏幕上。

答案 3 :(得分:0)

另一种解决方案是here。 segue将按钮操作更改为显示或关闭弹出窗口。