如何使用Swift让UIAlertController同时兼容iPhone和iPad
解决UIAlertController在iPad上崩溃的兼容问题
iPad上UIAlertController以actionSheet样式展示时,默认是popover弹窗形式,必须指定弹窗的锚点(触发它的控件位置),否则会因系统无法确定弹窗的显示位置而崩溃;而iPhone上actionSheet是全屏模态弹出,不需要锚点,所以能正常运行。
具体解决方案:
创建并配置UIAlertController后,通过它的popoverPresentationController属性设置锚点信息:
- 如果是通过
UIButton触发弹窗:
@IBAction func selectImageBtnTapped(_ sender: UIButton) { // 创建图片选择的AlertController let alert = UIAlertController(title: "选择图片", message: nil, preferredStyle: .actionSheet) // 添加操作选项 alert.addAction(UIAlertAction(title: "拍照", style: .default) { _ in // 执行拍照逻辑 }) alert.addAction(UIAlertAction(title: "从相册选取", style: .default) { _ in // 执行相册选取逻辑 }) alert.addAction(UIAlertAction(title: "取消", style: .cancel)) // 适配iPad:设置popover的锚点为触发按钮 if let popover = alert.popoverPresentationController { popover.sourceView = sender popover.sourceRect = sender.bounds // 可选:指定弹窗箭头的允许方向 popover.permittedArrowDirections = .any } present(alert, animated: true) }
- 如果是通过
UIBarButtonItem触发弹窗:
直接设置barButtonItem属性作为锚点即可:
if let popover = alert.popoverPresentationController { popover.barButtonItem = sender // sender为触发的UIBarButtonItem实例 }
关键说明:
- 无需判断设备类型,直接检查
popoverPresentationController是否存在即可(仅iPad上actionSheet样式的AlertController会生成这个对象)。 - 必须设置
sourceView/sourceRect或barButtonItem其中一项,否则iPad端必然崩溃。
内容的提问来源于stack exchange,提问作者WINS SAINI
相关产品推荐
相关产品推荐

