Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找UIAlertView而不引用它iOS 7_Ios_Objective C_Cocoa Touch_Ios7 - Fatal编程技术网

查找UIAlertView而不引用它iOS 7

查找UIAlertView而不引用它iOS 7,ios,objective-c,cocoa-touch,ios7,Ios,Objective C,Cocoa Touch,Ios7,我在我的项目中使用了一个代码片段,回答如下: 代码如下: + (UIAlertView *) getUIAlertViewIfShown { if ([[[UIApplication sharedApplication] windows] count] == 1) { return nil; } UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:1]

我在我的项目中使用了一个代码片段,回答如下:

代码如下:

+ (UIAlertView *) getUIAlertViewIfShown {
    if ([[[UIApplication sharedApplication] windows] count] == 1) {
        return nil;
    }

    UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
    if ([window.subviews count] > 0) {
        UIView *view = [window.subviews objectAtIndex:0];
        if ([view isKindOfClass:[UIAlertView class]]) {
            return (UIAlertView *) view;
        }
    }
    return nil;
}
不幸的是,它在iOS 7中不起作用,我无法取消警报视图。调试时,我发现在循环中,它显示视图属于类
UITransitionView
。非常混乱,因为我找不到此视图类的任何快速文档


有什么办法可以解决这个问题吗?

在iOS7中,
UIAlertView
窗口不会出现在
-[UIApplication windows]
中。事实上,
UIAlertView
本身从未添加到任何窗口,
-[UIAlertView窗口]
总是
nil
。相反,警报视图管理放置在
-[UIApplication keyWindow]
中的各种未记录视图,而不引用警报视图

在iOS7中,您唯一的实际选择是跟踪您的警报视图。

iOS 7解决方案

Class UIAlertManager = objc_getClass("_UIAlertManager");
UIAlertView *topMostAlert = [UIAlertManager performSelector:@selector(topMostAlert)];
我不确定AppStore是否认可它,但它确实有效

UPD单行代码:

UIAlertView *topMostAlert = [NSClassFromString(@"_UIAlertManager") performSelector:@selector(topMostAlert)];
这将不允许发布到苹果商店。在构建验证期间,Xcode将抛出一个错误,例如:“访问未记录的方法…”
因此您不能使用它,但是此代码运行良好。

您可以注册到
UIWindowDiBecomeVisibleNotification

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(aWindowBecameVisible:)
                                             name:UIWindowDidBecomeVisibleNotification
                                           object:nil];
并在aWindowBecameVisible中检查
\u UIModalItemHostingWin
的窗口描述:

if ([[theWindow description] hasPrefix:@"<_UIModalItemHostingWin"])
{
    // This is the alert window
}

if([[theWindow description]hasPrefix:@“我也遇到过类似的问题,在我的情况下,从视图控制器的不同实例显示警报,正如Brian已经提到的那样,
UIAlertView
窗口不会出现在iOS7的-
[UIApplication windows]

因此,为了跟踪这一情况,可以遵循以下方法:

  • 在应用程序委托中定义一个
    BOOL
    常量-

    @property (nonatomic, assign) BOOL isAlertVisibleOnAppWindow;
    
  • 如果存在“UIAlerView”,请检查早期实例是否存在-

    AppDelegate *delegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
    if (!delegate.isAlertVisibleOnAppWindow) {
        delegate.isAlertVisibleOnAppWindow = YES;
    
        UIAlertView *alertView = [[UIAlertView alloc] init…//alert init code
    
        // Either handle alert cancel/completeion click here via blocks, or use alert delegates to reset the isAlertVisibleOnAppWindow BOOL variable to NO.
    }
    

  • 这可能有助于其他人分享此信息。

    请保留对它的引用。是否可能有更多窗口?您只检查一个窗口。为什么不检查所有窗口?@Kevin我正在使用宏显示警报视图,而且使用频率太高。您的建议将是最后一个选项。@rmaddy我调试了代码并将其删除s在windows的数组中只返回一个对象。我修改了所有代码并保留了对警报视图的引用,现在它们工作正常。UIAlertView的窗口是-UIModalItemHostingWindow(私有API)如果我使用NSClassFromString而不是objc_getClass可以吗?这通过审查了吗?苹果允许吗?@TùngĐỗ当然,这在生产中是不允许的。对于集成测试来说,这可能是有帮助的,但在模拟器上它似乎不起作用。可能7.1扼杀了这一点。它不起作用。我在上传到appstore时得到错误引用非公共API。它不起作用。我在上传到appstore时得到错误引用非公共API。完美的方式…我如果你不想在应用商店上传你的应用
    AppDelegate *delegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
    if (!delegate.isAlertVisibleOnAppWindow) {
        delegate.isAlertVisibleOnAppWindow = YES;
    
        UIAlertView *alertView = [[UIAlertView alloc] init…//alert init code
    
        // Either handle alert cancel/completeion click here via blocks, or use alert delegates to reset the isAlertVisibleOnAppWindow BOOL variable to NO.
    }