You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现iPhone上ActionSheet从Bar Button弹出(仿微信+按钮效果)

解决iPhone上ActionSheet从按钮弹出的问题

我之前也遇到过一模一样的困扰!iPhone上默认用.actionSheet样式的UIAlertController会自动变成底部全屏弹出的样式,完全不是我们想要的popover效果,其实只要调整两个关键设置就能搞定:

核心思路

iPhone上默认的.actionSheet会自动适配为底部sheet,这时候系统会忽略popoverPresentationController的配置。我们需要强制让AlertController以popover形式展示,同时正确绑定触发源,就能实现像微信+按钮那样的弹出效果。

修改后的完整代码

@IBAction func addChannel(_ sender: Any) { 
    // 安全转换sender为UIBarButtonItem,避免类型错误
    guard let barButtonSender = sender as? UIBarButtonItem else { return }
    
    let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) 
    
    let addChanel = UIAlertAction(title: "Add a Channel", style: .default) { (_) in 
        self.addChannel() 
    } 
    let addContact = UIAlertAction(title: "Add a Contact", style: .default){ _ in 
        self.addContact() 
    } 
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
    
    actionSheet.addAction(addChanel) 
    actionSheet.addAction(addContact) 
    actionSheet.addAction(cancelAction) 
    
    // 关键:强制设置为popover展示样式,覆盖iPhone默认的底部sheet
    actionSheet.modalPresentationStyle = .popover
    if let popover = actionSheet.popoverPresentationController {
        popover.barButtonItem = barButtonSender
        popover.permittedArrowDirections = .down
    } 
    
    self.present(actionSheet, animated: true) 
}

为什么原来的代码不生效?

在iPhone上,当你给UIAlertController设置.actionSheet样式时,它的modalPresentationStyle默认是.automatic,系统会自动把它转为底部全屏的sheet样式,这时候即使你配置了popoverPresentationController,系统也不会使用这些设置。

而当我们把modalPresentationStyle强制设为.popover后,不管是iPad还是iPhone,都会遵循popover的展示逻辑,从你指定的barButtonItem位置弹出,完美实现你想要的效果。

内容的提问来源于stack exchange,提问作者Stan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:47:35