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

SwiftUI中实现Text长按手势跳转至另一界面的问题

解决方案

因为你的场景是在UIKit导航栈中嵌入SwiftUI页面,有两种可行的实现方式:

方式一:SwiftUI原生导航(推荐)

利用SwiftUI的NavigationStack和状态变量控制导航链接,这种方式能和UIKit的导航栈无缝协同:

  1. 修正ClassB的命名(Swift规范要求类型首字母大写):
struct ClassB: View {
    var body: some View {
        VStack(alignment: .leading){
            Text("Hello")
        }
        .navigationTitle("Class B")
    }
}
  1. 修改ClassA的代码,添加状态变量和导航逻辑:
struct ClassA: View {
    // 控制导航触发的状态变量
    @State private var shouldNavigateToClassB = false
    
    var body: some View {
        NavigationStack {
            VStack(alignment: .leading, spacing: 7) {
                Text("user 1")
                Text("Long Press Here")
                    .onLongPressGesture(minimumDuration: 2) {
                        // 触发导航跳转
                        shouldNavigateToClassB = true
                    }
                Text("User 2")
            }
            .navigationTitle("Class A")
            // 绑定状态的导航目标
            .navigationDestination(isPresented: $shouldNavigateToClassB) {
                ClassB()
            }
        }
    }
}

方式二:直接调用UIKit导航控制器

如果更习惯UIKit的导航逻辑,可以直接获取当前顶层导航控制器并push新的SwiftUI页面:

  1. 添加一个获取顶层导航控制器的扩展(可放在任意Swift文件中):
extension UIApplication {
    func topNavigationController() -> UINavigationController? {
        let keyWindow = connectedScenes
            .filter({$0.activationState == .foregroundActive})
            .compactMap({$0 as? UIWindowScene})
            .first?.windows
            .first(where: {$0.isKeyWindow})
        
        guard let rootVC = keyWindow?.rootViewController else { return nil }
        return findTopNavigationController(from: rootVC)
    }
    
    private func findTopNavigationController(from viewController: UIViewController) -> UINavigationController? {
        if let navVC = viewController as? UINavigationController {
            return navVC
        }
        for childVC in viewController.children {
            return findTopNavigationController(from: childVC)
        }
        return viewController.presentedViewController.flatMap { findTopNavigationController(from: $0) }
    }
}
  1. 修改ClassA的长按手势处理代码:
struct ClassA: View {
    var body: some View {
        VStack(alignment: .leading, spacing: 7) {
            Text("user 1")
            Text("Long Press Here")
                .onLongPressGesture(minimumDuration: 2) {
                    // 创建ClassB的托管控制器
                    let classBView = ClassB()
                    let hostingController = UIHostingController(rootView: classBView)
                    // 获取顶层导航控制器并执行push
                    UIApplication.shared.topNavigationController()?.pushViewController(hostingController, animated: true)
                }
            Text("User 2")
        }
        .navigationTitle("Class A")
    }
}

注意:请务必将原代码中的classB改为ClassB,符合Swift类型首字母大写的命名规范。

内容的提问来源于stack exchange,提问作者King

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:33:34