質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

6744閲覧

Swift3 UIAlertControllerの重複処理について

P-san

総合スコア21

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

1グッド

0クリップ

投稿2017/04/27 05:38

###前提・実現したいこと
swift3 にてUIAlertControllerでメッセージの表示をしているのですが、
メッセージが重複した際の処理で困っています。

すでにメッセージが表示されている状態で別のメッセージを表示してしまうと以下のエラーが出てしまうので
"すでになんらかのメッセージが表示されている場合は、次のメッセージを表示しない。"
という処理をしたいと思います。

しかし、コードが古いのか、根本的に間違っているのかうまく行きません。
何か良い方法はあるでしょうか。

よろしくお願いします。
###発生している問題・エラーメッセージ

Warning: Attempt to present ... while a presentation is in progress!

###該当のソースコード

swift

1 2// 外部からこのメッセージ表示クラスを呼ぶ。 3class Pop { 4 5 /// - Parameters: 6 /// - uIViewController: 呼び出し元で'self'を引数に指定します。 7 func message(_ uIViewController: UIViewController) { 8 9 // メッセージが表示されているかを判断したい。 10 // しかし、全て elseになってしまう。 11 if uIViewController.parent is AlertController { 12 return 13 } 14 // メッセージが表示されていなかったら表示 15 else { 16 17 let alert: UIAlertController = UIAlertController(title: "エラーです。", message: text , preferredStyle: UIAlertControllerStyle.alert) 18 let cancelAction: UIAlertAction = UIAlertAction(title: "確認", style: UIAlertActionStyle.cancel) { action in } 19 alert.addAction(cancelAction) 20 uIViewController.present(alert, animated: true, completion: nil) 21 } 22 } 23} 24
acevif👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

以下の様にして試してみてください。

swift

1// 外部からこのメッセージ表示クラスを呼ぶ。 2class Pop { 3 4 /// - Parameters: 5 /// - uIViewController: 呼び出し元で'self'を引数に指定します。 6 func message(_ uIViewController: UIViewController) { 7 8 guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { 9 return 10 } 11 12 while let presentedViewController = topViewController.presentedViewController { 13 topViewController = presentedViewController 14 } 15 16 if let _ = topViewController as? UIAlertController { 17 18 // アラートがすでに出ていたら再度出さない 19 return 20 } 21 22 23 let alert: UIAlertController = UIAlertController(title: "エラーです。", message: "テキスト" , preferredStyle: UIAlertControllerStyle.alert) 24 let cancelAction: UIAlertAction = UIAlertAction(title: "確認", style: UIAlertActionStyle.cancel) { action in } 25 alert.addAction(cancelAction) 26 uIViewController.present(alert, animated: true, completion: nil) 27 } 28}

投稿2017/04/27 14:01

_Kentarou

総合スコア8490

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

P-san

2017/04/28 01:27

ご回答ありがとうございます。 しかし、`return`がかからず、メッセージの表示処理が何回も実行されてしまいます。
guest

0

ベストアンサー

UIの状態を調べにいくより、変数で状態を管理するほうが設計の筋が良いと思います。

  • Pop が管理用の変数をもつ。たとえば var isPresented: Bool とか。
  • 表示処理の最初にこれをtrueにして、表示直後(アクションの中)とかでこれをfalseにする。
  • 管理用の変数isPresentedtrueなら、表示処理はおこなわない。

厳密には、isPresentedの読み書きはGCDとかつかって排他制御をしたほうがいいかもしれませんが、通常は上記で問題出ないでしょう。

投稿2017/05/04 02:56

編集2017/05/04 02:58
acevif

総合スコア59

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

P-san

2017/05/06 01:00

上手く処理できました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問