如何将UIAlertController封装到独立文件并从其中回调输入的数据?
问题原因
你当前的报错根源是原回调闭包没有定义输入参数,无法将弹窗内UITextField的输入值传递到外部业务逻辑,且你在外部业务代码中用到的nameFolderField是弹窗封装方法内的局部变量,外部作用域本来就无法直接访问。同时原回调未加@escaping声明,作为异步调用的逃逸闭包也会触发编译错误。
解决步骤
- 第一步:修改弹窗封装方法的回调定义,增加字符串类型的参数,用于传递用户输入的合法文本
- 第二步:在标注
// -----here----的校验通过位置,调用回调时将输入框文本作为参数传入 - 第三步:外部调用弹窗方法时,在回调的参数中拿到输入文本,执行你的业务逻辑即可
修改后的封装代码
extension UIViewController { // 增加@escaping声明、给闭包增加String类型的入参 func alertEditSum(nameCell: String, completion: @escaping ((String) -> Void)) { let alertController = UIAlertController(title: "Hello", message: "", preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "Save", style: .default , handler: { _ in guard let nameFolderField = alertController.textFields?.first, let inputText = nameFolderField.text, nameFolderField.isTextFieldCheck(text: inputText) else { return } // -----here---- 校验通过后把输入文本传给回调 completion(inputText) })) alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) alertController.addTextField(configurationHandler: { nameField in nameField?.clearButtonMode = .always nameField?.keyboardType = .decimalPad })) self.present(alertController, animated: true) } }
外部调用示例代码
// 在你需要触发弹窗的位置调用即可 alertEditSum(nameCell: "传入你的业务参数") { [weak self] inputText in guard let self = self, let payment = Double(inputText) else { return } self.sortedDate[indexPath.section - 1].personPayment = payment do { try self.context.save() self.collectionView.reloadData() } catch { // 可自行补充存储失败的兜底逻辑 print("数据保存失败: \(error.localizedDescription)") } }
额外优化说明
- 移除了原代码中所有强制解包(
!)语法,避免输入异常、数据非法场景下的App崩溃 - 增加
[weak self]避免闭包循环引用导致的内存泄漏 - 替换强制
try!为do-catch异常捕获,提升代码稳定性
内容的提问来源于stack exchange,提问作者PollyVern
相关产品推荐
相关产品推荐

