我有一个方法可以发布HTTP数据并在出现错误时显示UIAlertView。如果我有多个HTTP帖子,我将为每个错误显示多个UIAlertView。
我只想在没有显示其他UIAlertView的情况下显示UIAlertView。 我该如何确定?
答案 0 :(得分:59)
为什么不检查由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];
}
答案 1 :(得分:52)
在调用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;
}
如果您希望按顺序显示警报,我会发布通知以将每条消息添加到队列中,然后仅在取消警报后从队列中取消消息。
答案 2 :(得分:25)
如果您可以控制其他警报视图,请检查每个警报视图的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不能抱怨这一点。更可靠但更无证的方法是检查if [_UIAlertManager visibleAlert]
is nil。
这些方法无法检查是否显示了SpringBoard的UIAlertView。
答案 3 :(得分:9)
- (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;
}
答案 4 :(得分:4)
另一个适用于整个应用程序并且不涉及遍历视图堆栈的选项是将UIAlertView
子类化为MyUIAlertView
,添加静态(类)变量BOOL alertIsShowing
,并覆盖-(void)show
选择器。
在覆盖的show
选择器中,检查alertIsShowing
变量。如果是YES
,请在延迟后重试(使用dispatch_after
或设置NSTimer
)。如果是NO
,请继续致电[super show]
并将YES
分配给alertIsShowing
;隐藏警报视图时,将alertIsShowing
设置回NO
(您需要聪明地处理委托)。
最后,请使用UIAlertView
替换所有MyUIAlertView
个实例。
答案 5 :(得分:4)
我认为它会起作用:
-(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
}
答案 6 :(得分:3)
夫特:
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)
}
}
答案 7 :(得分:2)
// 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
}
答案 8 :(得分:2)
+ (BOOL)checkAlertExist {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
if ([window.rootViewController.presentedViewController isKindOfClass:[UIAlertController class]]) {
return YES;
}
}
return NO;
}
答案 9 :(得分:1)
关于我在视图层次结构中查找UIAlertView的一些注意事项:
我试图以递归方式遍历所有[UIApplication sharedApplication].windows
视图,但找不到任何内容。
windows
docs的UIApplication
属性声明如下:
此属性包含当前与之关联的UIWindow对象 该应用程序。 此列表不包含由。创建和管理的窗口 系统,例如用于显示状态栏的窗口。
所以这让我意识到UIWindow
所在的UIAlertView
甚至没有呈现给我们。
但是,UIApplication
上还有一个名为keyWindow
的媒体资源。循环完成后,我发现了构成警报视图的私有类:
在iOS 7上:_UIModalItemHostingWindow
,_UIModalItemAlertContentView
,_UIBackdropEffectView
等。
在iOS 8上:_UIAlertControllerActionView
,_UIAlertControllerShadowedScrollView
,_UIBackdropView
等。
我找不到我提出的UIAlertView
,而是一堆内部组成的类。 因此,要回答原始问题,您可以使用keyWindow
属性并查看是否注意到这些类,但是您的应用可能会因尝试检查私有类而被拒绝。
对于使用的人来说,适用于iOS 8的较新的UIAlertController
可以使用以下方式获取对它的引用:
[UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController
。