我使用Xcode故事板(所以没有代码)从UIBarButtonItem
创建了一个弹出程序,如下所示:
呈现波波夫效果很好。然而,当我点击使其出现的UIBarButtonItem
时,我无法让弹出器消失。
当(第一次)按下按钮时,就会出现弹出器。当再次按下按钮(第二次),同样的弹出会出现在上面,所以现在我有两个弹出(如果我继续按这个按钮的话)。根据iOS人机界面指南,我需要使弹出器出现在第一个点击上,然后在第二个按钮上消失:
确保一次只有一个弹出窗口在屏幕上可见。您不应该同时显示多个popover (或自定义视图,其外观和行为类似于popover)。特别是,您应该避免同时显示层叠或层次结构,其中一个弹出器是从另一个弹出的。
当用户第二次点击UIBarButtonItem
时,我如何排除弹出窗口呢?
发布于 2012-04-19 16:10:09
编辑:这些问题似乎在iOS 7.1 / Xcode 5.1.1中得到了修复。(可能更早,因为我还不能测试所有版本。当然是在iOS 7.0之后,因为我测试了这个版本。)当您从UIBarButtonItem
创建一个popover时,segue确保再次点击该弹出盖隐藏该弹出,而不是显示一个重复。它也适用于Xcode 6为UIPresentationController
8创建的新的-based弹出插件。
由于我的解决方案可能对那些仍然支持早期iOS版本的人具有历史意义,所以我将其放在下面。
如果您存储了对segue的popover控制器的引用,然后在重复调用prepareForSegue:sender:
时将其设置为一个新的值,那么您所避免的就是在重复按下按钮时获得多个堆叠弹出的问题--您仍然不能按照HIG的建议(以及在苹果的应用程序中看到,等等)使用该按钮来关闭弹出器。
不过,您可以利用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 {
// 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
没有第三步!
这里使用零位弱引用的好处是,一旦弹出控制器被取消--无论是以编程方式在shouldPerformSegueWithIdentifier:
中,还是通过用户在弹出器之外的某个地方自动地点击-- ivar再次进入nil
,所以我们回到了初始状态。
如果不对弱引用进行归零,我们还必须:
myPopover = nil
中删除它时设置它,以及popoverControllerDidDismissPopover:
,并在那里设置myPopover = nil
(因此,当popover被自动取消时,我们就会捕获)。发布于 2011-11-28 11:51:13
我在这里找到了解决方案--在第一个prepareForSegue:https://stackoverflow.com/a/7938513/665396:https://stackoverflow.com/a/7938513/665396中,将指向UIPopoverController和用户的指针存储在一个ivar/属性中,以便在随后的调用中排除该弹出。
...
@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;
...
}
发布于 2012-03-11 06:17:03
我用过定制的曲目。
1
创建要在童话板中使用的自定义segue:
@implementation CustomPopoverSegue
-(void)perform
{
// "onwer" of popover - it needs to use "strong" reference to retain UIPopoverReference
ToolbarSearchViewController *source = self.sourceViewController;
UIViewController *destination = self.destinationViewController;
// create UIPopoverController
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:destination];
// source is delegate and owner of popover
popoverController.delegate = source;
popoverController.passthroughViews = [NSArray arrayWithObject:source.searchBar];
source.recentSearchesPopoverController = popoverController;
// present popover
[popoverController presentPopoverFromRect:source.searchBar.bounds
inView:source.searchBar
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
@end
2
在视图中,控制器是segue的源/输入,例如,使用action启动segue:
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
if(nil == self.recentSearchesPopoverController)
{
NSString *identifier = NSStringFromClass([CustomPopoverSegue class]);
[self performSegueWithIdentifier:identifier sender:self];
}
}
3.
引用是由创建UIPopoverController的segue分配的--当删除popover时
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
if(self.recentSearchesPopoverController)
{
[self.recentSearchesPopoverController dismissPopoverAnimated:YES];
self.recentSearchesPopoverController = nil;
}
}
你好,彼得
https://stackoverflow.com/questions/8287242
复制