iPad全局函数中present ActionSheet样式UIAlertController崩溃问题
iPad上全局函数中展示ActionSheet样式UIAlertController的崩溃解决方法
问题原因
iPad上,.actionSheet样式的UIAlertController默认采用UIModalPresentationPopover展示模式,必须指定弹出位置(sourceView+sourceRect或barButtonItem),否则会触发崩溃。但全局函数类没有直接的视图对象引用,需通过其他方式获取合法的视图源。
解决步骤
添加全局方法获取顶层可见控制器
实现一个UIViewController扩展,用来获取当前应用最上层的可见视图控制器(适配iOS13+多场景模式):extension UIViewController { static func topMostViewController() -> UIViewController? { var topVC = UIApplication.shared.connectedScenes .filter({$0.activationState == .foregroundActive}) .compactMap({$0 as? UIWindowScene}) .first?.windows .filter({$0.isKeyWindow}).first?.rootViewController while let presentedVC = topVC?.presentedViewController { topVC = presentedVC } return topVC } }修改AlertController弹出代码
在原代码中加入popover位置配置逻辑,同时增加兜底方案避免极端情况崩溃:let langs = try? VNRecognizeTextRequest.supportedRecognitionLanguages(for: .fast, revision: 2) let alertController = UIAlertController(title: "Select Language".localized, message: nil, preferredStyle: .actionSheet) for lang in langs ?? []{ let title = GlobalFunctions.getLanguageNameFrom(code: lang) let action = UIAlertAction(title: title, style: .default) { action in completion?(lang) } alertController.addAction(action) } let actionCancel = UIAlertAction(title: "Cancel".localized, style: .cancel, handler: nil) alertController.addAction(actionCancel) // 配置popover弹出位置 if let popover = alertController.popoverPresentationController { guard let topVC = UIViewController.topMostViewController(), let sourceView = topVC.view else { // 兜底:无法获取顶层控制器时,切换为alert样式避免崩溃 alertController.preferredStyle = .alert return } popover.sourceView = sourceView // 设置弹窗在屏幕中心弹出 popover.sourceRect = CGRect(x: sourceView.bounds.midX, y: sourceView.bounds.midY, width: 0, height: 0) // 隐藏箭头(可选,根据需求调整) popover.permittedArrowDirections = [] } AppDelegate.shared.window?.rootViewController?.present(alertController, animated: true, completion: nil)
额外说明
- 如果调用全局函数的场景有明确触发源(如按钮),建议让调用方传入
barButtonItem或sourceView+sourceRect,弹窗位置会更贴合交互逻辑。 - 兜底逻辑中切换为
.alert样式是为了保证极端情况下应用的可用性。
内容的提问来源于stack exchange,提问作者user2296278
相关产品推荐
相关产品推荐

