如何解雇故事板Popover [英] How to Dismiss a Storyboard Popover

查看:79
本文介绍了如何解雇故事板Popover的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Xcode Storyboards(所以没有代码)从 UIBarButtonItem 创建了一个popover,如下所示:





介绍popover工作得很好。但是,当我点击显示它的 UIBarButtonItem 时,我无法将消失



按下按钮(第一次)时会出现弹出窗口。当再次按下该按钮时(第二次),它上面会出现相同的弹出窗口,所以现在我有两个弹出窗口(如果我继续按下按钮,则会有更多弹出窗口)。根据 iOS人机界面指南我需要让弹出窗口出现在第一次点击并在第二次点击时消失:


确保一次只能在屏幕上显示一个弹出窗口。您不应同时显示多个弹出窗口(或设计为外观和行为的自定义视图)。特别是,你应该避免同时显示一个级联或层次结构的弹出窗口,其中一个弹出窗口从另一个弹出窗口出现。


我如何解雇当用户第二次点击 UIBarButtonItem 时,popover?

解决方案

编辑:自iOS 7.1 / Xcode 5.1.1起,这些问题似乎已得到修复。 (可能更早,因为我无法测试所有版本。绝对是在iOS 7.0之后,因为我测试了那个。)当你从 UIBarButtonItem 创建一个popover segue时,segue确保再次点击弹出窗口隐藏弹出窗口而不是显示重复。它适用于Xcode 6为iOS 8创建的基于 UIPresentationController 的popover segues。



自我的解决方案对那些仍然支持早期iOS版本的人来说可能具有历史意义,我把它留在了下面。






如果你存储对segue的popover控制器的引用,在重复调用 prepareForSegue:sender:之前将其设置为新值之前解除它,所有你避免的是获得多个堆叠的问题重复按下按钮时弹出窗口 - 您仍然无法使用该按钮来关闭HIG推荐的弹出窗口(如Apple的应用程序中所示)



你可以利用ARC归零弱引用来获得一个简单的解决方案,但是:



1:从按钮开始搜索



从iOS 5开始,你无法使用来自 UIBarButtonItem 的segue,但你可以在iOS 6及更高版本上使用。 (在iOS 5上,您必须从视图控制器本身中删除,然后在检查弹出窗口后按钮的动作调用 performSegueWithIdentifier:。)



2:在 -shouldPerformSegue中使用对popover的引用...



  @interface ViewController 
@property(weak)UIPopoverController * myPopover;
@end

@implementation ViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
//如果你有多个segues ,检查segue.identifier
self.myPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
}
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if(self.myPopover){
[self.myPopover dismissPopoverAnimated:YES] ;
返回NO;
} else {
返回YES;
}
}
@end



3:没有步骤三个!



在这里使用归零弱引用的好处是,一旦弹出控制器被解除 - 无论是以编程方式在中还是应该是PerformSegueWithIdentifier:,或者用户在弹出窗口外的其他位置自动点击 - ivar再次转到 nil ,所以我们回到了初始状态。 / p>

如果没有归零弱引用,我们还必须:




  • set myPopover = nil 中删除​​它时,应该在@PerformSegueWithIdentifier:

  • 将自己设置为popover控制器的委托,以便捕获 popoverControllerDidDismissPopover:并在那里设置 myPopover = nil (所以当弹出时我们抓住被自动解雇。)


I've created a popover from a UIBarButtonItem using Xcode Storyboards (so there's no code) like this:

Presenting the popover works just fine. However, I can't get the popover to disappear when I tap the UIBarButtonItem that made it appear.

When the button is pressed (first time) the popover appears. When the button is pressed again (second time) the same popover appears on top of it, so now I have two popovers (or more if I continuer pressing the button). According to the iOS Human Interface Guidelines I need to make the popover appear on the first tap and disappear on the second:

Ensure that only one popover is visible onscreen at a time. You should not display more than one popover (or custom view designed to look and behave like a popover) at the same time. In particular, you should avoid displaying a cascade or hierarchy of popovers simultaneously, in which one popover emerges from another.

How can I dismiss the popover when the user taps the UIBarButtonItem for a second time?

解决方案

EDIT: These problems appear to be fixed as of iOS 7.1 / Xcode 5.1.1. (Possibly earlier, as I haven't been able to test all versions. Definitely after iOS 7.0, since I tested that one.) When you create a popover segue from a UIBarButtonItem, the segue makes sure that tapping the popover again hides the popover rather than showing a duplicate. It works right for the new UIPresentationController-based popover segues that Xcode 6 creates for iOS 8, too.

Since my solution may be of historical interest to those still supporting earlier iOS versions, I've left it below.


If you store a reference to the segue's popover controller, dismissing it before setting it to a new value on repeat invocations of prepareForSegue:sender:, all you avoid is the problem of getting multiple stacking popovers on repeated presses of the button -- you still can't use the button to dismiss the popover as the HIG recommends (and as seen in Apple's apps, etc.)

You can take advantage of ARC zeroing weak references for a simple solution, though:

1: Segue from the button

As of iOS 5, you couldn't make this work with a segue from a UIBarButtonItem, but you can on iOS 6 and later. (On iOS 5, you'd have to segue from the view controller itself, then have the button's action call performSegueWithIdentifier: after checking for the popover.)

2: Use a reference to the popover in -shouldPerformSegue...

@interface ViewController
@property (weak) UIPopoverController *myPopover;
@end

@implementation ViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // if you have multiple segues, check segue.identifier
    self.myPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
}
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    if (self.myPopover) {
        [self.myPopover dismissPopoverAnimated:YES];
        return NO;
    } else {
        return YES;
    }
}
@end

3: There's no step three!

The nice thing about using a zeroing weak reference here is that once the popover controller is dismissed -- whether programmatically in shouldPerformSegueWithIdentifier:, or automatically by the user tapping somewhere else outside the popover -- the ivar goes to nil again, so we're back to our initial state.

Without zeroing weak references, we'd have to also:

  • set myPopover = nil when dismissing it in shouldPerformSegueWithIdentifier:, and
  • set ourself as the popover controller's delegate in order to catch popoverControllerDidDismissPopover: and also set myPopover = nil there (so we catch when the popover is automatically dismissed).

这篇关于如何解雇故事板Popover的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆