查找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.
}