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クラスによって維持される可視プロパティだけをチェックしないのはなぜですか?
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];
}
- (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;
}
アプリ全体で機能し、ビュースタックのウォークを伴わない別のオプションは、UIAlertView
をMyUIAlertView
にサブクラス化し、静的(クラス)変数_BOOL alertIsShowing
_を追加し、 -(void)show
セレクター。
オーバーライドされたshow
セレクターで、alertIsShowing
変数を確認します。 YES
の場合、しばらくしてからもう一度試してください(_dispatch_after
_を使用するか、NSTimer
を設定します)。 NO
の場合は、_[super show]
_を呼び出して、YES
をalertIsShowing
に割り当てます。アラートビューが非表示になったら、alertIsShowing
をNO
に設定し直します(デリゲートの処理について賢くする必要があります)。
最後に、すべてのUIAlertView
インスタンスをMyUIAlertView
に置き換えます。
私はそれがうまくいくと思う:
-(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
}
迅速:
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)checkAlertExist {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
if ([window.rootViewController.presentedViewController isKindOfClass:[UIAlertController class]]) {
return YES;
}
}
return NO;
}
// 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
}
ビュー階層で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
を使用して参照することができます。