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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:24:03