iPadでActionSheetを表示する時に気を付けること
iOSアプリの開発で、複数ある選択肢から一つを選ぶUIとして「ActionSheet」があります。
これは非常にわかりやすいUIなのですが、iPadではうまく動かないことがあります。
今回はそんな、ちょっとニッチな情報を書いていこうと思います。
環境
今回の環境は下記の通りです。
Swift 5
Xcode 10.3
iOS 12.4
iPhoneでは動くがiPadでは動かないコード
実際に問題となるActionSheetの出し方を見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@IBAction func touchUpButton(_ sender: UIButton) { // この辺で権限チェックをする // 画像選択の手段を表示 let actionSheet = UIAlertController(title: "画像選択", message: nil, preferredStyle: .actionSheet) actionSheet.addAction(UIAlertAction(title: "カメラ", style: .default, handler: { (action:UIAlertAction) in self.openImagePicker(.camera) })) actionSheet.addAction(UIAlertAction(title: "ライブラリ", style: .default, handler: { (action:UIAlertAction) in self.openImagePicker(.photoLibrary) })) actionSheet.addAction(UIAlertAction(title: "キャンセル", style: .cancel, handler: { (action:UIAlertAction) in })) self.present(actionSheet, animated: true, completion: nil) } |
特に問題は無いように思われるプログラムコードですし、実際にこういう記述を書かれる方は多いと思います。
事実、このプログラムを iPhone で動かした場合、何もエラーは起きません。
ただし iPad で動かした場合 「libc++abi.dylib: terminating with uncaught exception of type NSException」 というエラーでアプリケーションがクラッシュします。
対処方法
iPhoneにはなく、iPadにある機能の一つで PopoverPresentationController というものがあります。
これが指定されていないためにクラッシュしてしまうエラーのようですので、指定してあげれば解決します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
@IBAction func touchUpButton(_ sender: UIButton) { // この辺で権限チェックをする // 画像選択の手段を表示 let actionSheet = UIAlertController(title: "画像選択", message: nil, preferredStyle: .actionSheet) actionSheet.addAction(UIAlertAction(title: "カメラ", style: .default, handler: { (action:UIAlertAction) in self.openImagePicker(.camera) })) actionSheet.addAction(UIAlertAction(title: "ライブラリ", style: .default, handler: { (action:UIAlertAction) in self.openImagePicker(.photoLibrary) })) actionSheet.addAction(UIAlertAction(title: "キャンセル", style: .cancel, handler: { (action:UIAlertAction) in })) // iPad の場合のみ、ActionSheetを表示するための必要な設定 if UIDevice.current.userInterfaceIdiom == .pad { actionSheet.popoverPresentationController?.sourceView = self.view let screenSize = UIScreen.main.bounds actionSheet.popoverPresentationController?.sourceRect = CGRect(x: screenSize.size.width / 2, y: screenSize.size.height, width: 0, height: 0) } self.present(actionSheet, animated: true, completion: nil) } |
UIDevice.current.userInterfaceIdiom で起動しているデバイスが判断できます
さいごに
このエラーはシミュレータでも発生しますので、気になる人は試してみると良いと思います。
他にもiPadのみの機能として、SplitViewやSlideOverなどもありますし、
画面サイズなどによっても大きく異なることがあると思います。
また iPadアプリはiPhoneの画面を大きくしたもの という誤認識をされている方も見受けられますが、UI/UXにおいて大きく異なりますし、開発工数も変わってきてしまいます。
ユニバーサル(iPhone/iPadの両方対応したもの)アプリを作る際には気を付けていきましょう。
- おすすめ記事
-
-
のえる2019.08.06
-
POPULAR
のえる
Full-stack Developer