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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

Q&A

解決済

1回答

1692閲覧

別クラスからアラートが表示されない

takk_014

総合スコア53

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2021/04/06 01:33

編集2021/04/06 01:37

ViewControllerではない別のクラスからアラートを表示させたいです。
下記のコードで存在しない郵便番号があったらアラートを表示させようとしています。

swift

1import Foundation 2import UIKit 3import GoogleMaps 4 5class PostalCodeConversion: UIViewController{ 6 //CLGeocoderインスタンスを取得(郵便番号を位置情報に変換するAPI) 7 let geocoder = CLGeocoder() 8 static let VC = ViewController() 9 10 func conversion(postalCode: String, mapView: GMSMapView!){ 11 //郵便番号から緯度経度を取得 12 CLGeocoder().geocodeAddressString(postalCode) { placemarks, error in 13 if let lat = placemarks?.first?.location?.coordinate.latitude, 14 let lng = placemarks?.first?.location?.coordinate.longitude{ 15 print("↓検索結果の座標↓") 16 print("緯度 : (lat)") 17 print("経度 : (lng)") 18 let camera = GMSCameraPosition.camera(withLatitude:lat,longitude:lng,zoom:13.0) 19 mapView.animate(to: camera) 20 } 21 else{ 22 print("error") 23 print(Thread.isMainThread) 24 // アラートダイアログを生成 25 let alertController = UIAlertController(title: "エラー",message:"存在しない郵便番号です。", 26 preferredStyle: UIAlertController.Style.alert) 27 // OKボタンの詳細設定 28 let okAction = UIAlertAction(title: "はい",style: UIAlertAction.Style.default, handler: { action in}) 29 // OKボタンを追加 30 alertController.addAction(okAction) 31 // アラートダイアログを表示 32 PostalCodeConversion.VC.present(alertController, animated: true, completion: nil) 33 } 34 } 35 } 36} 37

しかし実行するとこのようにエラーが出力されてダイアログが出てこないです。

[Presentation] Attempt to present <UIAlertController: 0x1030d7000> on <Direction_Sample.ViewController: 0x102578800> (from <Direction_Sample.ViewController: 0x102578800>) whose view is not in the window hierarchy.

調べたところViewControllerクラス以外でpresentは実行できないとのことですがクラス分けしたいためViewControllerクラス以外でpresentを実行したいです。
Thread.isMainThreadはtrueを返しており、メインスレッドであることは確認済みです。
ご教授よろしくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

swift

1// 前略... 2if let frontViewController = UIApplication.shared.keyWindow?.rootViewController { 3 while frontViewController.presentedViewController { 4 frontViewController = frontViewController.presentedViewController; 5 } 6 frontViewController.present(alertController, animated: true, completion: nil) 7} else { 8 // 必要に応じたなんらかの例外処理 9}

調べたところViewControllerクラス以外でpresentは実行できない

ところで、これはまあそうなのですが、これは問題の本質ではないですね。
ViewControllerの上に別のViewControllerをpresentするとき、

  • 基礎となる側のViewControllerが、View Hierarchyの中に存在していること
  • 基礎となる側のViewControllerが、View Hierarchyの一番上 (上に別のViewControllerがpresentされていない) にあること

の2点が必要で、この1点目が満たされていないとエラーメッセージは指摘しています。

PostalCodeConversion.VC.present(_,animated:,completion:) で呼び出そうとしていますが、 PostalCodeConversion.VC は次の行で static で宣言されていますね。

swift

1class PostalCodeConversion: UIViewController{ 2 //CLGeocoderインスタンスを取得(郵便番号を位置情報に変換するAPI) 3 let geocoder = CLGeocoder() 4 static let VC = ViewController() // <-

なぜstaticで宣言しているのかわかりませんが、staticを外して、PostalCodeConversionのインスタンスを生成しているViewController側で次のような感じにしてもいいと思います

swift

1// 基礎となる側 2let conversion = new PostalCodeConversion() 3conversion.VC = self 4 5// PostalCodeConversion側 6 // OKボタンの詳細設定 7 let okAction = UIAlertAction(title: "はい",style: UIAlertAction.Style.default, handler: { action in}) 8 // OKボタンを追加 9 alertController.addAction(okAction) 10 // アラートダイアログを表示 11 self.VC.present(alertController, animated: true, completion: nil) 12// ^^^^

投稿2021/04/06 01:51

編集2021/04/06 02:07
thyda.eiqau

総合スコア2982

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

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

takk_014

2021/04/06 02:09

どういう原理か分かりませんがそのコードを下に添えるだけでアラートが表示できるようになりました。 コードの単語から察するにpresentedViewControllerによる描画を最前に持ってきているのでしょうか・・・ とりあえずありがとうございます!!
thyda.eiqau

2021/04/06 02:36

どういう原理かわかっていないものをコピペで使うのは大変危険なのでやめましょう。クラスとメソッド、インスタンス、継承、あたりもわかってなさそうなので、まずは理解することをおすすめします。極論ですが私が書いたコードが省庁や他国の軍のサーバーを攻撃する内容だったらどうするのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問