web-dev-qa-db-ja.com

UIAlertViewが表示されているかどうかを確認します

HTTPデータをポストし、エラーがある場合にUIAlertViewを表示するメソッドがあります。複数のHTTPポストがある場合、エラーごとに複数のUIAlertViewを表示します。

他のUIAlertViewを表示していない場合にのみ、UIAlertViewを表示したい。これをどのように判断できますか?

41
Ricibald

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;
}

アラートを順番に表示する場合は、通知を投稿して各メッセージをキューに追加し、アラートが破棄された後にのみメッセージをキューから削除します。

53
Chip Coons

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];
}
60
Koen
- (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;
}
9
Javen.Yang

アプリ全体で機能し、ビュースタックのウォークを伴わない別のオプションは、UIAlertViewMyUIAlertViewにサブクラス化し、静的(クラス)変数_BOOL alertIsShowing_を追加し、 -(void)showセレクター。

オーバーライドされたshowセレクターで、alertIsShowing変数を確認します。 YESの場合、しばらくしてからもう一度試してください(_dispatch_after_を使用するか、NSTimerを設定します)。 NOの場合は、_[super show]_を呼び出して、YESalertIsShowingに割り当てます。アラートビューが非表示になったら、alertIsShowingNOに設定し直します(デリゲートの処理について賢くする必要があります)。

最後に、すべてのUIAlertViewインスタンスをMyUIAlertViewに置き換えます。

4
damian

私はそれがうまくいくと思う:

-(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
}
4
Manab Kumar Mal

迅速:

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)
    }
}
3
Morgan
+ (BOOL)checkAlertExist {

    for (UIWindow* window in [UIApplication sharedApplication].windows) {
        if ([window.rootViewController.presentedViewController isKindOfClass:[UIAlertController class]]) {
            return YES;
        }
    }
    return NO;
}
2
Pach
// 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
}
2
Jemythehigh

ビュー階層で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を使用して参照することができます。

1
kgaidis