Sam*_*cer 73 objective-c uibarbuttonitem uipopovercontroller ios uistoryboard
我UIBarButtonItem使用Xcode Storyboards 创建了一个popover (所以没有代码),如下所示:

提出popover工作得很好.但是,当我点击它使它出现时,我无法让popover 消失UIBarButtonItem.
按下按钮(第一次)时会出现弹出窗口.当再次按下该按钮(第二次)时,它上面会出现相同的弹出窗口,所以现在我有两个弹出窗口(如果我继续按下按钮,则会有更多弹出窗口).根据iOS人机界面指南,我需要在第一次点击时显示弹出窗口并在第二次点击时消失:
确保一次只能在屏幕上看到一个弹出窗口.您不应同时显示多个弹出窗口(或设计为外观和行为的自定义视图).特别是,您应该避免同时显示级联或层次结构的弹出窗口,其中一个弹出窗口从另一个弹出窗口出现.
当用户UIBarButtonItem再次点击时,如何解除popover ?
ric*_*ter 114
编辑:从iOS 7.1/Xcode 5.1.1开始,这些问题似乎已得到修复.(可能更早,因为我无法测试所有版本.绝对是在iOS 7.0之后,因为我测试了那个.)当你从a创建一个popover segue时UIBarButtonItem,segue确保再次点击popover隐藏了popover而不是而不是显示重复.它适用于UIPresentationControllerXcode 6为iOS 8创建的新的popover segues.
由于我的解决方案可能对仍然支持早期iOS版本的人有历史意义,我将其留在下面.
如果您存储对segue的弹出控制器的引用,在重复调用时将其设置为新值之前将其解除prepareForSegue:sender:,您可以避免重复按下按钮时获得多个堆栈弹出窗口的问题 - 您仍然无法使用按照HIG的建议解除弹出窗口的按钮(如Apple的应用程序中所示)
但是,您可以利用ARC归零弱引用来获得简单的解决方案:
从iOS 5开始,你无法使用来自a的segue UIBarButtonItem,但你可以在iOS 6及更高版本中使用.(在iOS 5上,您必须从视图控制器本身中删除,然后performSegueWithIdentifier:在检查弹出窗口后进行按钮的动作调用.)
-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
Run Code Online (Sandbox Code Playgroud)
在这里使用归零弱引用的好处是,一旦弹出控制器被解除 - 无论是以编程方式进入shouldPerformSegueWithIdentifier:,还是由用户在弹出窗口外的其他位置自动攻击 - ivar nil再次进入,所以我们回到我们的初始状态.
在没有归零弱引用的情况下,我们还必须:
myPopover = nil在解雇时设置shouldPerformSegueWithIdentifier:,和popoverControllerDidDismissPopover:并设置myPopover = nil那里(所以我们在弹出窗口被自动解除时捕获).小智 13
我在这里找到了解决方案/sf/answers/555695941/ 在第一个prepareForSegue:sender:存储在ivar/property中指向UIPopoverController的指针和用户指向在后续调用中解除popover的指针.
...
@property (nonatomic, weak) UIPopoverController* storePopover;
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue
sender:(id)sender {
if ([segue.identifier isEqualToString:@"My segue"]) {
// setup segue here
[self.storePopover dismissPopoverAnimated:YES];
self.storePopover = ((UIStoryboardPopoverSegue*)segue).popoverController;
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45870 次 |
| 最近记录: |