我使用Xcode故事板(所以没有代码)从UIBarButtonItem创建了一个弹出窗口,如下所示:

Xcode 5.0带有Popover的连接判断器

展示爆米花效果很好.但是,当我点击使其出现的UIBarButtonItem时,无法将弹出窗口调到disappear.

当(第一次)按下按钮时,弹出窗口出现.当再次按下按钮(第二次)时,相同的弹出窗口会出现在它的顶部,所以现在我有两个弹出窗口(如果我继续按按钮,会有更多的弹出窗口).根据iOS Human Interface Guidelines,我需要使弹出窗口在第一次点击时出现,在第二次点击时消失:

确保屏幕上一次只能看到一个popover.您不应同时显示多个popover(或设计为外观和行为类似popover的自定义视图).特别是,应该避免同时显示级联或层次 struct 的popover,即一个popover从另一个popover中出现.

当用户再次点击UIBarButtonItem时,我如何解除弹出窗口?

推荐答案

EDIT:从IOS 7.1/Xcode 5.1.1开始,这些问题似乎已得到解决.(可能更早,因为我无法测试所有版本.肯定是在iOS 7.0之后,因为我测试了那个.)当您从UIBarButtonItem创建弹出窗口段时,段会确保再次点击弹出窗口会隐藏弹出窗口,而不是显示副本.它也适用于Xcode6为iOS8创建的基于UIPresentationController的新Popover segues.

由于我的解决方案可能对那些仍然支持早期iOS版本的人具有历史意义,所以我将其留在下面.


如果您存储了对Segue的Popover控制器的引用,在重复调用prepareForSegue:sender:时将其设置为新值之前将其取消,那么您所避免的就是重复按下按钮时会出现多次堆叠弹出的问题--您仍然不能像HIG建议的那样使用该按钮来取消Popover(正如苹果的应用程序等所看到的那样).

不过,对于简单的解决方案,您可以利用ARC将弱引用置零的优势:

1:从按钮开始分段

从iOS5开始,你不能用UIBarButtonItem的片段来做这件事,但是你可以在iOS6和更高版本上做这件事.(在iOS5上,您必须与视图控制器本身分开,然后在判断弹出窗口后让按钮的操作调用performSegueWithIdentifier:.)

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:没有第三步!

这里使用零弱引用的好处是,一旦取消了popover控制器--无论是以编程方式进入shouldPerformSegueWithIdentifier:,还是通过用户在popover之外的其他地方自动点击--ivar又回到了nil,所以我们回到了初始状态.

如果不将弱引用归零,我们还必须:

  • shouldPerformSegueWithIdentifier:中取消时设置myPopover = nil,并且
  • 将自己设置为popover控制器的代理,以便捕捉popoverControllerDidDismissPopover:,并在那里设置myPopover = nil(因此,当popover被自动解除时,我们捕捉).

Ios相关问答推荐

StackView UIKit间距似乎非常小的编程式编程

与iPadOS中带有扣件的模式相似的组件是什么?

使用AVCaptureEventInteraction捕获音量按键快门

如何将模糊输入/模糊输出添加到SwiftUI中的非对称过渡?

在 Swift 中,对象如何被准确地从内存中移除?

SKScene 的更新功能似乎不起作用

SwiftUI:如何为 ScrollView 制作可拉伸(灵活)的粘性标题?

.overlay 和 body 是什么 swift 概念

Xcode - 错误 ITMS-90635 - Bundle 包中的 Mach-O 无效 - 提交到 App Store

CocoaPods 找不到 podFirebase/Core的兼容版本 | cloud_firestore, Flutter

SwiftUI 视图 - viewDidLoad()?

如何在 Swift 中使用包含多个值的查询参数构建一个 URL?

向标签栏控制器添加新标签

如何找出用于构建 *.ipa 文件的配置文件?

'无效更新:第 0 节中的无效行数

是否可以将 Socket.io 与 AWS Lambda 一起使用?

iOS在应用程序中下载并保存图像

如何在 iphone 屏幕中间显示活动指示器?

如何删除UITableView中最后一个单元格的最后一个边框?

Xcode中的终端窗口?