在 iPad 中关闭原生 UIActionsheet 和 UIPopover

Posted

技术标签:

【中文标题】在 iPad 中关闭原生 UIActionsheet 和 UIPopover【英文标题】:Dismiss native UIActionsheet & UIPopover in iPad 【发布时间】:2013-09-30 15:37:53 【问题描述】:

这个问题是指在 iPad 的 webview/textview 中选择电话号码或电子邮件时显示操作表和弹出框的原生 ios 功能。如果您需要复习,操作表包含两个按钮,分别为“添加到联系人”和“复制”。我所指的弹出框是用户选择“添加到联系人”按钮时显示的内容。

我明白要解除弹出框声明:

[somePopoverController dismissPopoverAnimated:YES];

要关闭操作表,只需调用:

[someActionSheet dismissWithClickedButtonIndex:0 animated:YES];

但是,我的问题是,由于 iOS 为我创建了这些操作表/弹出框,我不拥有它们,并且无法引用它们来调用解除方法。

我需要这样做的用例是因为我的应用程序将在指定的无活动时间后注销用户。当用户退出时,这些操作表/弹出框仍然保留在屏幕上,即使我已经输入了一个新的视图控制器并删除了旧的。

有谁知道我可以如何引用这些我不拥有的弹出框和操作表?任何建议将不胜感激!

【问题讨论】:

【参考方案1】:

好吧,我找到了一种解决方案,可以在 iPad 上检测电话号码/电子邮件时同时消除 UIActionSheets 和从 Webviews/Textviews 创建的弹出框。解决方案基本上是使用递归遍历我的所有视图,直到找到我想要忽略的视图。我在这篇帖子Accessing UIPopoverController for UIActionSheet on iPad 中找到的答案要归功于我。

要删除 UIActionSheets:

BOOL IsActionOpen(UIView* aView) 
    BOOL    actionOpen = NO;
    if (aView) 
        if ([aView isKindOfClass:[UIActionSheet class]]) 
            actionOpen = YES;
            [(UIActionSheet *)aView dismissWithClickedButtonIndex:0 animated:NO];
        
        else if (aView.subviews.count > 0) 
            for (UIView* aSubview in aView.subviews) 
                if ( IsActionOpen( aSubview)) 
                    if ([aView isKindOfClass:[UIActionSheet class]]) 
                        actionOpen = YES;
                        [(UIActionSheet *)aView dismissWithClickedButtonIndex:0 animated:NO];
                    break;
                
            
        
    
    return actionOpen;


- (void) removeActionSheetIfShowing 
    BOOL    actionOpen = NO;
    for (UIWindow* w in [UIApplication sharedApplication].windows) 
        actionOpen =  IsActionOpen(w);
        if (actionOpen)
            break;
    

删除从生成的 UIActionSheet 中选择“添加到联系人”按钮时创建的弹出框:

BOOL IsPopOverOpen(UIView* aView) 
    BOOL    popOverOpen = NO;
    if (aView) 
        //popover is a popoverview, not a popovercontroller. We find it by checking if UIPopoverBackgroundView exists
        if([aView isKindOfClass:[UIPopoverBackgroundView class]])
            popOverOpen = YES;
            [aView.superview removeFromSuperview];
        
        else if (aView.subviews.count > 0) 
            for (UIView* aSubview in aView.subviews) 
                if ( IsPopOverOpen( aSubview)) 
                    if([aView isKindOfClass:[UIPopoverBackgroundView class]])
                        popOverOpen = YES;
                        [aView.superview removeFromSuperview];
                    break;
                
            
        
    
    return popOverOpen;


- (void) removePopOverIfShowing 
    BOOL    popOverOpen = NO;
    for (UIWindow* w in [UIApplication sharedApplication].windows) 
        popOverOpen =  IsPopOverOpen(w);
        if (popOverOpen)
            break;
    

【讨论】:

【参考方案2】:

您只需要在视图控制器中保留对它们的引用即可。 例如,当您创建UIActionSheet 时,只需将其存储在UIActionSheet 类型的属性中

@property (strong, nonatomic) UIActionSheet *myActionSheet;

然后,当您实际创建操作表时,您会这样做

self.myActionSheet = [[UIActionSheet alloc] initWithTitle:myTitle 
                                                 delegate:self 
                                        cancelButtonTitle:cancelButtonTitle 
                                   destructiveButtonTitle:destButtonTitle 
                                        otherButtonTitles:otherButtonTitle, nil];

[self.myActionSheet showFromBarButtonItem:sender animated:YES];

当你需要关闭它时,你只需这样做

[self.myActionSheet dismissWithClickedButtonIndex:0 animated:YES];

【讨论】:

感谢您的回复,但我认为您的回答对我没有帮助。问题是我实际上从未在代码中创建 UIAction 表。 iOS 为我“神奇地”构建了操作表,因为在 webview/textview 中只有一个电子邮件/电话号码。 哦,好的,我现在明白你的意思了

以上是关于在 iPad 中关闭原生 UIActionsheet 和 UIPopover的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机反应中关闭模态

在 iOS 上的 Fine-uploader 中关闭相机

无法从另一个类中关闭 UIPopover

何时在 Nodejs 中关闭 MongoDB 数据库连接

iPad actionsjeet

在 UIViewController 中关闭键盘