检查是否显示UIAlertView

2020/12/17 01:51 · ios ·  · 0评论

我有一种发布HTTP数据并在出现错误时显示UIAlertView的方法。如果我有多个HTTP帖子,我将为每个错误显示多个UIAlertView。

我只想在不显示其他UIAlertView的情况下显示UIAlertView。我该如何确定?

在调用的对象上,在调用UIAlertView上的show方法之前,请设置一个ivar。

...

if (!self.alertShowing) {
    theAlert = [[UIAlertView alloc] initWithTitle:title message:details delegate:self cancelButtonTitle:nil otherButtonTitles:@"Okay", nil];
    self.alertShowing = YES;
    [theAlert show];
}

...

然后在警报的委托方法中,将标志ivar设置为no:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
  ...
      self.alertShowing = NO;
}

如果希望警报按顺序显示,我将发布通知以将每条消息添加到队列中,然后仅在解除警报后将消息从队列中移出。

为什么不只检查UIAlertView类维护的visible属性呢?

if (_alert) //alert is a retained property
{
    self.alert = [[[UIAlertView alloc] initWithTitle:@"Your Title"
                                             message:@"Your message" 
                                            delegate:self
                                   cancelButtonTitle:@"Cancel"
                                   otherButtonTitles:@"OK"] autorelease];
}
if (!_alert.visible)
{
    [_alert show];
}

如果您可以控制其他警报视图,请检查visible每个警报视图的属性。


在iOS 6或更低版本中,当出现警报时,它将被移动到_UIAlertOverlayWindow。因此,一种非常脆弱的方法是遍历所有窗口并检查是否有UIAlertView子视图。

for (UIWindow* window in [UIApplication sharedApplication].windows) {
  NSArray* subviews = window.subviews;
  if ([subviews count] > 0)
    if ([[subviews objectAtIndex:0] isKindOfClass:[UIAlertView class]])
      return YES;
}
return NO;

尽管Apple对此没有抱怨,但是这取决于内部视图层次结构,因此没有记录。一种更可靠但更未公开的方法是检查是否[_UIAlertManager visibleAlert]为nil

这些方法无法检查是否显示了SpringBoard的UIAlertView。

- (BOOL)checkAlertExist {
    for (UIWindow* window in [UIApplication sharedApplication].windows) {
        NSArray* subviews = window.subviews;
        if ([subviews count] > 0) {
            for (id cc in subviews) {
                if ([cc isKindOfClass:[UIAlertView class]]) {
                    return YES;
                }
            }
        }
    }
    return NO;
}

横跨整个应用的工作方式,并不涉及行走视图栈的另一个选项是子类UIAlertViewMyUIAlertView添加一个静态(类)变量BOOL alertIsShowing,并覆盖-(void)show选择。

在覆盖的show选择器中,检查alertIsShowing变量。如果是YES,请在延迟后重试(使用dispatch_after或设置NSTimer)。如果是NO,请继续呼叫[super show]并分配YESalertIsShowing当警报视图被隐藏时,将其设置alertIsShowingNO(需要聪明地处理委托)。

最后,检查并用替换所有UIAlertView实例MyUIAlertView

迅速:

func showAlert(withTitle title: String, message: String, viewController: UIViewController) {
    if viewController.presentedViewController == nil { // Prevent multiple alerts at the same time
        let localizedTitle = NSLocalizedString(title, comment: "")
        let localizedMessage = NSLocalizedString(message, comment: "")
        let alert = UIAlertController(title: localizedTitle, message: localizedMessage, preferredStyle: .Alert)
        let action = UIAlertAction(title: "OK", style: .Default, handler: nil)
        alert.addAction(action)

        viewController.presentViewController(alert, animated: true, completion: nil)
    }
}

我认为它将起作用:

-(BOOL) doesAlertViewExist {
    if ([[UIApplication sharedApplication].keyWindow isMemberOfClass:[UIWindow class]])
    {
        return NO;//AlertView does not exist on current window
    }
    return YES;//AlertView exist on current window
}
// initialize default flag for alert... If alert is not open set isOpenAlert as NO
BOOL isAlertOpen;
isAlertOpen = NO;
if (isAlertOpen == NO) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Alert is Open" delegate:self cancelButtonTitle:@"Okay!!" otherButtonTitles: nil];
    [alert show];
    // Now set isAlertOpen to YES
    isAlertOpen = YES;
}
else
{
    //Do something
}
+ (BOOL)checkAlertExist {

    for (UIWindow* window in [UIApplication sharedApplication].windows) {
        if ([window.rootViewController.presentedViewController isKindOfClass:[UIAlertController class]]) {
            return YES;
        }
    }
    return NO;
}

我在视图层次结构中寻找UIAlertView的一些注意事项:

我试图[UIApplication sharedApplication].windows递归遍历所有视图,但是找不到任何东西。

docswindows属性UIApplication指出以下内容:

此属性包含当前与应用程序关联的UIWindow对象。该列表不包括由系统创建和管理的窗口,例如用于显示状态栏的窗口。

因此,这让我意识到,UIWindow这里UIAlertView可能位于甚至没有呈现在我们面前。

但是,还有一个UIApplication名为的属性keyWindow循环遍历之后,我发现了组成警报视图的私有类:

在iOS 7: ,等。_UIModalItemHostingWindow_UIModalItemAlertContentView_UIBackdropEffectView

在iOS 8: ,等。_UIAlertControllerActionView_UIAlertControllerShadowedScrollView_UIBackdropView

我找不到UIAlertView我介绍的内容,而是一堆内部组成它的类。因此,要回答原始问题,您可能可以使用该keyWindow属性,看看是否注意到这些类,但是您的应用可能会因为尝试检查私有类而被拒绝。

对于使用的人,UIAlertController适用于iOS 8的较新版本可以使用对其进行引用
[UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController

本文地址:http://ios.askforanswer.com/jianchashifouxianshiuialertview.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!