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)
}
}
こんな感じでいけました。