質問

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

...

次に、アラートを管理するためのデリゲートメソッドでは、旗の設定を管理します。

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

他のアラートビューを制御できる場合は、 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はこれについて文句を言うことはできませんが、これは内部ビューの階層に依存するため、文書化されていません。より信頼性が高いが、さらに文書化されていない方法はチェックすることです もしも [_UIAlertManager visibleAlert] ニルです.

これらのメソッドは、スプリングボードからのuialertviewが表示されているかどうかを確認できません。

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

アプリ全体で動作し、ビュースタックのウォーキングを伴わない別のオプションは、サブクラスです UIAlertViewMyUIAlertView, 、静的(クラス)変数を追加します BOOL alertIsShowing, 、そしてオーバーライドします -(void)show セレクタ。

あなたのオーバーライドされています show セレクター、チェックします alertIsShowing 変数。もし YES 次に、遅延後に再試行してください(使用してください dispatch_after または設定します NSTimer)。もし NO, 、先に進んで電話してください [super show] 割り当てます YESalertIsShowing;アラートビューが隠されたら、設定します 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)
    }
}
// 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
}
+ (BOOL)checkAlertExist {

    for (UIWindow* window in [UIApplication sharedApplication].windows) {
        if ([window.rootViewController.presentedViewController isKindOfClass:[UIAlertController class]]) {
            return YES;
        }
    }
    return NO;
}

ビュー階層でuialertviewを見つけるための私の探求に関するいくつかのメモ:

私はすべてのループをループしようとしました [UIApplication sharedApplication].windows ビューは再帰的にありますが、何も見つかりませんでした。

windows の財産 UIApplication docsは次のように述べています。

このプロパティには、現在アプリに関連付けられているuiwindowオブジェクトが含まれています。 このリストには、システムによって作成および管理されたWindowsは含まれていません, 、ステータスバーの表示に使用されるウィンドウなど。

それで、これは私にそれを実現させました UIWindow どこ UIAlertView 見つけることができます。

ただし、プロパティもあります UIApplication 呼び出されました keyWindow. 。それをループすると、アラートビューを構成するプライベートクラスを見つけました。

iOS 7: _UIModalItemHostingWindow, _UIModalItemAlertContentView, _UIBackdropEffectView

iOS 8で: _UIAlertControllerActionView, _UIAlertControllerShadowedScrollView, _UIBackdropView

私は見つけることができませんでした UIAlertView 私が提示したが、むしろ、それを内部で構成するクラスの束を提示したこと。 元の質問に答えるために, 、おそらく使用できます keyWindow プロパティとこれらのクラスに気付くかどうかを確認しますが、アプリはプライベートクラスをチェックしようとするために拒否される可能性があります。

使用している人々のために、より新しい、 UIAlertController iOS 8で利用可能なことは、以下を使用してそれを参照することができます。[UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top