iPadでアクションシートが開かない問題に対処する


本記事は「デジタルサイネージアプリ「Sign!」(iOS版)とその実装機能の紹介」の子記事です。

目的

iPadでアクションシート(.actionSheet)タイプのダイアログ(UIAlertController)が開かない場合の対処方法を説明します。

開発・実行環境

  • 開発環境:macOS、Xcode(9~10)、Swift(4~5)
  • 実行環境:iOS 11以上

コード

別の記事「ダイアログを表示する」で、ダイアログ(UIAlertController)を生成する際、「preferredStyle」に「.actionSheet」を選択できることを書きましたが、iPadでアクションシート(.actionSheet)を開くには、present()を実行する前に、1行加える必要があります。

ViewController.swift
override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  let dialog = UIAlertController(title: "Dialog Title", message: "Message is here", preferredStyle: .actionSheet)
  dialog.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
  dialog.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
  dialog.popoverPresentationController?.sourceView = self.view  // この行を追加
  self.present(dialog, animated: true, completion: nil)
}

iPadの場合、アクションシートはポップアップメニュー的に扱われますが、ポップアップする対象のビュー(.sourceView)を指定する必要があり、上記「この行」が、それに該当します。この例では、ViewControllerのviewを指定しています。
ちなみに、ダイアログは以下のようになります。

iPad画面の左上に表示されます。ステータスバーに食い込んでいるのはご愛嬌(サンプルプログラムのViewのレイアウト指定をサボりました)。
ちなみに、「Cancel」は表示されません。ダイアログの外をタップすると、「Cancel」が選択されたものとして処理されます。

以上です。