SwiftUI使用UIViewControllerRepresentable传参后delegate不生效如何解决
问题1:尾随闭包报错「Extra trailing closure passed in call」
原因:PaymentWrapper定义了foo回调属性,但现有初始化方法仅接收viewModel一个参数,没有预留回调的入参位置,调用时传入尾随闭包就会报参数多余错误。
修复方案:修改init方法,将foo作为入参,支持尾随闭包语法:
// 修改后的init方法 public init(viewModel: CartViewModel, foo: @escaping (String) -> Void) { self.viewModel = viewModel self.foo = foo }
问题2:delegate无法正常触发
原因有两个:
- 你把
CustomUIPaymentViewController作为PaymentWrapper的存储属性,SwiftUI的视图是值类型,随时可能被系统重建,存储的UIKit控制器实例极易出现异常失效 - 原写法在
PaymentWrapper的init中创建控制器,此时foo属性还未完成赋值,后续给控制器绑定delegate的逻辑也存在时序问题
完整修复代码
struct PaymentWrapper: UIViewControllerRepresentable { typealias UIViewControllerType = CustomUIPaymentViewController @ObservedObject var viewModel: CartViewModel var foo: (String) -> Void // 新增foo入参,支持尾随闭包 public init(viewModel: CartViewModel, foo: @escaping (String) -> Void) { self.viewModel = viewModel self.foo = foo } func makeUIViewController(context: Context) -> CustomUIPaymentViewController { // 控制器只在makeUIViewController中创建,不做存储 let vc = CustomUIPaymentViewController(token: viewModel.mtToken) // 直接绑定coordinator作为delegate,保证生效 vc.delegate = context.coordinator return vc } func updateUIViewController(_ uiViewController: CustomUIPaymentViewController, context: Context) { // 按需更新控制器逻辑 } func makeCoordinator() -> Coordinator { Coordinator(foo: foo) } class Coordinator: NSObject, CustomUIPaymentViewControllerDelegate, CustomUINavigationControllerDelegate { var foo: (String) -> Void init(foo: @escaping (String) -> Void) { self.foo = foo super.init() } func paymentViewController(_ viewController: CustomUIPaymentViewController!, paymentFailed error: Error!) { foo("FAILED") } func paymentViewController(_ viewController: CustomUIPaymentViewController!, paymentPending result: TransactionResult!) { foo("PENDING") } func paymentViewController(_ viewController: CustomUIPaymentViewController!, paymentSuccess result: TransactionResult!) { foo("SUCCESS") } func paymentViewController_paymentCanceled(_ viewController: CustomUIPaymentViewController!) { foo("CANCEL") } func paymentViewController(_ viewController: CustomUIPaymentViewController!, paymentDeny result: TransactionResult!) { // 按需实现逻辑 } } } struct CartView: View { @ObservedObject var viewModel = CartViewModel() var body: some View { VStack { Header(title: "Cart", back: false) } .sheet(isPresented: $viewModel.showPayment) { // 现在尾随闭包可正常传入 PaymentWrapper(viewModel: self.viewModel) { data in print(data) } } } }
核心改动说明
- 移除了控制器存储属性,避免SwiftUI视图重建导致的实例异常
- 初始化方法新增回调参数,解决尾随闭包报错问题
- 控制器创建和delegate绑定逻辑移到
makeUIViewController中,保证delegate绑定时序正确,回调可正常触发
内容的提问来源于stack exchange,提问作者Charas
相关产品推荐
相关产品推荐

