SwiftUI内嵌UIViewController触发NavigationLink非预期跳转问题求解
问题根源
你当前的写法存在两个核心问题:
NavigationLink默认会捕获自身label区域内的所有点击事件,自动将绑定的isActive状态置为true,和你在UIViewController中手动控制状态的逻辑冲突ContentView中@ObservedObject修饰的overlayShow默认初始化了新实例,和外部传入的实例不一致,会导致状态同步失效
修复方案
步骤1:拆分导航链接与交互视图
不要将可交互的OnboardingWrapper作为NavigationLink的label,改为将无交互的EmptyView作为导航链接的载体,放到视图背景中,只有手动修改isShowingOverlay才会触发导航。
步骤2:统一状态实例
删除ContentView中overlayShow的默认初始化,确保全局只用同一个OverlayShow实例。
修复后代码示例
兼容iOS13及以上版本
struct ContentView: View { // 移除默认初始化,保证使用外部传入的唯一实例 @ObservedObject var overlayShow: OverlayShow // 如果当前View是实例持有者,iOS14+推荐改为@StateObject: // @StateObject private var overlayShow = OverlayShow() var body: some View { NavigationView { OnboardingWrapper(overlayShow: overlayShow) .background( // 导航链接放到背景,label用EmptyView不会响应点击 NavigationLink( destination: OverlayView(overlay: LoadingUnknownOverlayViewContainer(description: "it is spinning :0", designModel: LoadingOverlayDesignModel(type: .unknown))), isActive: $overlayShow.isShowingOverlay, label: { EmptyView() } ) ) } } }
iOS16及以上推荐写法
用新的NavigationStack+navigationDestinationAPI实现,逻辑更清晰:
struct ContentView: View { @ObservedObject var overlayShow: OverlayShow var body: some View { NavigationStack { OnboardingWrapper(overlayShow: overlayShow) .navigationDestination(isPresented: $overlayShow.isShowingOverlay) { OverlayView(overlay: LoadingUnknownOverlayViewContainer(description: "it is spinning :0", designModel: LoadingOverlayDesignModel(type: .unknown))) } } } }
内容的提问来源于stack exchange,提问作者tara tandel
相关产品推荐
相关产品推荐

