使用UINavigationController时SwiftUI的onChange未触发问题求助
SwiftUI与UIKit混合导航下ObservableObject的onChange不触发问题
项目背景
- 需支持iOS 14
- 采用SwiftUI+UIKit混合开发,必须使用
UINavigationController作为窗口根控制器(否则无法推送UIKit视图控制器)
根控制器配置代码
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene else { return } let window = UIWindow(windowScene: windowScene) window.makeKeyAndVisible() window.overrideUserInterfaceStyle = .light self.window = window // UIKit Navigation 作为根控制器 let rootView = AnyView(SwiftUIView1()) let rootVC = UIHostingController(rootView: rootView) let rootNavC = UINavigationController(rootViewController: rootVC) window.rootViewController = rootNavC }
注:原代码中存在笔误
rootHubVC,已修正为rootVC
SwiftUIView1与ObservableObject定义
class TestingState: ObservableObject, Equatable { static func == (lhs: TestingState, rhs: TestingState) -> Bool { lhs.currentJourneyLevel == rhs.currentJourneyLevel } @Published var currentJourneyLevel: Int { willSet { debugPrint("##### currentJourneyLevel will be set from \(currentJourneyLevel) to \(newValue)") } } init() { currentJourneyLevel = 1 } } struct SwiftUIView1: View { @StateObject private var testingState = TestingState() @State var isActived = false { didSet { debugPrint("##### isActived: \(isActived)") } } var body: some View { VStack (spacing: 30) { Button("NextPage") { testingState.currentJourneyLevel = 2 } NavigationLink( destination: SwiftUIView2(state: testingState), isActive: $isActived ) { EmptyView() } } .onChange(of: testingState.currentJourneyLevel) { currentJourneyLevel in debugPrint("##### currentJourneyLevel is onChange to: \(currentJourneyLevel)") isActived = currentJourneyLevel == 2 } .navigationTitle("SwiftUIView1") .navigationBarTitleDisplayMode(.inline) } }
注:原代码中存在两处笔误已修正:
TestingState的==方法中错误比较lhs自身属性,已改为比较rhs对应属性NavigationLink的目标视图错误写为SwiftUIView1,已改为SwiftUIView2
SwiftUIView2代码
struct SwiftUIView2: View { private var state: TestingState init(state: TestingState) { self.state = state } var body: some View { ZStack { VStack(spacing: 10) { Button("Back") { state.currentJourneyLevel = 1 } } .navigationTitle("SwiftUIView2") } } }
问题现象
- 点击"NextPage"按钮时功能正常,日志输出:
"##### currentJourneyLevel will be set from 1 to 2" "##### currentJourneyLevel is onChange to: 2" "##### isActived: true"
- 点击"Back"按钮时,仅输出:
"##### currentJourneyLevel will be set from 2 to 1"
currentJourneyLevel已变更,但SwiftUIView1中的onChange闭包未触发。
3. 若改用纯SwiftUI的NavigationView导航,点击"Back"按钮时onChange正常触发,日志输出:
"##### currentJourneyLevel will be set from 2 to 1" "##### currentJourneyLevel is onChange to: 1" "##### isActived: false"
提问
如何让onChange在UINavigationController作为根控制器的情况下正常触发?或是我的代码存在操作错误?
内容的提问来源于stack exchange,提问作者Alanc Liu
相关产品推荐
相关产品推荐

