Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

[SwiftUI]iPadでActionSheetが使えないという事実をねじ伏せる

More than 1 year has passed since last update.

SwiftUIにはActionSheetというクラスがあり、文字通りUIAlertControllerのactionSheetスタイルを表示することが出来ます。
しかし、iPadではこれを使うと

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController (<UIAlertController: 0x7fb7118d8200>) of style UIAlertControllerStyleActionSheet from _TtGC7SwiftUI19UIHostingControllerGV11SwiftUIFlux13StoreProviderV9NightfoxS8AppStateVS3_10RouterView__ (<_TtGC7SwiftUI19UIHostingControllerGV11SwiftUIFlux13StoreProviderV9NightfoxS8AppStateVS3_10RouterView__: 0x7fb711503250>). The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem.  If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'
*** First throw call stack:

というメッセージが出てクラッシュします。
このワークアラウンドとしてAlertを使うことも出来るのですが、こちらは

Alert(title: Text, primaryButton: Alert.Button, secondaryButton: Alert.Button

といった2つのボタンしか設定出来ません。

まぁでもおそらく内部的にUIAlertControllerのイニシャライザを叩いていると思うので、必ずalertスタイルにすれば行けるはずです。

extension UIAlertController {
    static func forceAlertStyle() {
        let originalSelector = #selector(UIAlertController.init(title:message:preferredStyle:))
        let swizzledSelector = #selector(UIAlertController.nfs_init(title:message:preferredStyle:))

        let originalMethod = class_getClassMethod(UIAlertController.self, originalSelector)!
        let swizzledMethod = class_getClassMethod(UIAlertController.self, swizzledSelector)!

        method_exchangeImplementations(originalMethod, swizzledMethod)
    }

    @objc class func nfs_init(title: String?, message: String?, preferredStyle: UIAlertController.Style) -> UIAlertController {
        return UIAlertController.nfs_init(title: title, message: message, preferredStyle: .alert)
    }
}

スクリーンショット 2019-11-07 1.09.04.png

こんな感じでいけました。

noppefoxwolf
きつねすき、にんげんこわい
https://noppelab.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away