Swift中底部弹窗VC如何用无返回值函数实现自定义回调?
如何配置ViewController触发无返回值回调及Swift无返回值函数解析
一、主ViewController配置步骤
在弹出InfoSheeetViewController的主ViewController中,只需在初始化并展示弹窗的逻辑里,为callbackActionPressed赋值你需要执行的回调代码即可,示例代码如下:
class MainViewController: UIViewController { // 触发底部弹窗的按钮点击事件 @IBAction func showInfoSheet(_ sender: UIButton) { // 从Storyboard初始化弹窗VC(代码创建则用init方法) let infoSheetVC = UIStoryboard(name: "Main", bundle: nil) .instantiateViewController(withIdentifier: "InfoSheeetViewController") as! InfoSheeetViewController // 设置底部弹窗样式 infoSheetVC.modalPresentationStyle = .pageSheet if let sheet = infoSheetVC.sheetPresentationController { sheet.detents = [.medium(), .large()] // 自定义弹窗高度选项 sheet.prefersGrabberVisible = true // 显示顶部拖拽手柄 } // 配置回调逻辑:弹窗按钮点击后执行的操作 infoSheetVC.callbackActionPressed = { [weak self] in guard let self = self else { return } // 这里写具体业务逻辑,比如刷新页面、提示用户等 print("弹窗按钮已触发,执行回调") self.refreshMainPageData() } // 弹出弹窗 present(infoSheetVC, animated: true) } // 示例回调执行的业务方法 private func refreshMainPageData() { // 实现你的业务逻辑 } }
二、Swift无返回值函数(()->())工作机制
1. 类型本质
()->()是Swift函数类型的简写形式,等价于() -> Void:
- 左边的
()表示该函数没有输入参数 - 右边的
()/Void表示该函数没有返回值
它本质是一种闭包类型——可以捕获上下文变量的自包含代码块,你可以把它看作一段能被传递、在需要时才执行的代码。
2. 安全调用逻辑
在InfoSheeetViewController的按钮点击方法中,用了self.callbackActionPressed?()这种可选链调用:
- 如果主VC已经给
callbackActionPressed赋值了闭包(即不为nil),则执行这段闭包代码 - 如果没有赋值,调用会直接忽略,避免空指针崩溃
3. 内存注意事项
闭包会自动捕获上下文中的变量(比如示例里的self),如果不处理可能导致循环引用:
- 主VC持有弹窗VC,弹窗VC的闭包又持有主VC,两者无法被释放,造成内存泄漏
- 解决方法是在闭包开头添加
[weak self]弱引用,并用guard let self = self else { return }确保安全访问
内容的提问来源于stack exchange,提问作者Bima J Hermid
相关产品推荐
相关产品推荐

