SwiftUI跳转UIKit后第三方SDK授权页关闭触发根视图onAppear问题
SwiftUI集成第三方SDK后关闭授权页触发根视图onAppear的问题排查与解决
问题成因分析
从你的代码和场景来看,核心矛盾出在SwiftUI视图层级与UIKit第三方SDK控制器的交互逻辑上,具体原因可归纳为以下几点:
- 你在
LoginView中用@State var showMob控制隐藏的MobLoginBridging控制器显示,但授权页关闭后未主动将showMob设为false,导致无用的UIViewController实例长期驻留在SwiftUI视图树中,引发视图层级不稳定,间接触发根视图的onAppear方法。 - 第三方SDK的授权页以模态方式弹出后,关闭时的内部
dismiss逻辑与SwiftUI的导航栈产生冲突,导致SwiftUI错误感知到根视图需要重新渲染。 MobLoginController的生命周期未与SwiftUI状态绑定,授权页关闭后控制器未被正确销毁,触发视图树重绘。
解决方案
方案1:绑定授权页关闭状态到SwiftUI的@State
通过给MobLoginController添加回调闭包,在授权页关闭时通知SwiftUI更新状态,及时移除无用控制器:
// 修改MobLoginController,增加关闭回调 class MobLoginController: UIViewController, SVSDKVerifyDelegate { var onAuthDismiss: (() -> Void)? // 新增回调闭包 override func viewDidLoad() { super.viewDidLoad() DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { SVSDKHyVerify.preLogin { result, err in guard err == nil, let result = result else { return } print(result["operator"] as Any) SVSDKHyVerify.setDelegate(self) let mobConfig = SVSDKHyUIConfigure() mobConfig.currentViewController = self mobConfig.manualDismiss = true SVSDKHyVerify.openAuthPage(withModel: mobConfig, openAuthPageListener: { _, _ in }, cancelAuthPageListener: { [weak self] _, _ in // 授权页关闭时触发回调 self?.onAuthDismiss?() }, oneKeyLoginListener: { _, _ in }) } } } } // 修改MobLoginBridging,传递回调参数 struct MobLoginBridging: UIViewControllerRepresentable { var onDismiss: () -> Void // 新增回调参数 typealias UIViewControllerType = MobLoginController func makeUIViewController(context: Context) -> MobLoginController { let controller = MobLoginController() controller.onAuthDismiss = onDismiss return controller } func updateUIViewController(_ uiViewController: MobLoginController, context: Context) {} } // 修改LoginView,接收回调更新状态 struct LoginView: View { @State private var showMob: Bool = false var body: some View { Text("click to login") .onTapGesture { showMob.toggle() } if showMob { MobLoginBridging(onDismiss: { showMob = false // 关闭授权页后移除桥接控制器 }) .frame(width: 0, height: 0) } } }
方案2:改用SwiftUI模态方式托管SDK控制器
替代嵌入隐藏控制器的方式,用.fullScreenCover或.sheet管理SDK控制器的生命周期,让SwiftUI更可控:
struct LoginView: View { @State private var showMobSheet: Bool = false var body: some View { Text("click to login") .onTapGesture { showMobSheet.toggle() } .fullScreenCover(isPresented: $showMobSheet) { MobLoginBridging(onDismiss: { showMobSheet = false }) .background(Color.clear) // 隐藏桥接视图,仅保留SDK授权页 } } }
方案3:检查第三方SDK配置
确认mobConfig.manualDismiss = true的设置是否符合SDK要求,部分SDK在手动关闭模式下需要主动调用SVSDKHyVerify.closeAuthPage()方法,避免SDK内部错误操作导航栈。
内容的提问来源于stack exchange,提问作者rookie
相关产品推荐
相关产品推荐

