SwiftUI 导航

SwiftUI 提供了多种导航方式,让我为你详细介绍主要的导航模式和相关组件。

基本用法

swift 复制代码
struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                NavigationLink("前往详情页", value: "详情内容")
                NavigationLink("设置", value: "设置页面")
            }
            .navigationDestination(for: String.self) { value in
                DetailView(content: value)
            }
        }
    }
}

struct DetailView: View {
    let content: String
    
    var body: some View {
        Text("详情: \(content)")
            .navigationTitle("详情页")
    }
}

多类型导航

swift 复制代码
enum Route: Hashable {
    case product(Int)
    case category(String)
    case settings
}

struct ContentView: View {
    var body: some View {
        NavigationStack {
            VStack {
                NavigationLink("产品123", value: Route.product(123))
                NavigationLink("电子产品", value: Route.category("electronics"))
                NavigationLink("设置", value: Route.settings)
            }
            .navigationDestination(for: Route.self) { route in
                switch route {
                case .product(let id):
                    ProductView(productId: id)
                case .category(let name):
                    CategoryView(category: name)
                case .settings:
                    SettingsView()
                }
            }
        }
    }
}
swift 复制代码
struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: DetailView()) {
                    Label("详情页面", systemImage: "star")
                }
                NavigationLink(destination: SettingsView()) {
                    Label("设置", systemImage: "gear")
                }
            }
            .navigationTitle("主页面")
        }
    }
}

3. 编程式导航

swift 复制代码
struct ContentView: View {
    @State private var navigationPath = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $navigationPath) {
            VStack(spacing: 20) {
                Button("跳转到产品页") {
                    navigationPath.append(Route.product(456))
                }
                
                Button("跳转到分类页") {
                    navigationPath.append(Route.category("books"))
                }
                
                Button("多层级跳转") {
                    navigationPath.append(Route.category("electronics"))
                    navigationPath.append(Route.product(789))
                }
                
                Button("返回根页面") {
                    navigationPath.removeLast(navigationPath.count)
                }
                
                Button("上一步") {
                    guard !navigationPath.isEmpty else { return }
                    navigationPath.removeLast()
                }
            }
            .navigationDestination(for: Route.self) { route in
                // 路由处理...
            }
        }
    }
}

4. Sheet 和 FullScreenCover

模态展示

swift 复制代码
struct ContentView: View {
    @State private var showingSheet = false
    @State private var showingFullScreen = false
    
    var body: some View {
        VStack(spacing: 20) {
            Button("显示 Sheet") {
                showingSheet = true
            }
            
            Button("全屏显示") {
                showingFullScreen = true
            }
        }
        .sheet(isPresented: $showingSheet) {
            SheetView()
        }
        .fullScreenCover(isPresented: $showingFullScreen) {
            FullScreenView()
        }
    }
}

struct SheetView: View {
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        NavigationView {
            Text("这是 Sheet 视图")
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button("完成") {
                            dismiss()
                        }
                    }
                }
        }
    }
}

5. TabView 标签导航

swift 复制代码
struct MainTabView: View {
    var body: some View {
        TabView {
            HomeView()
                .tabItem {
                    Label("首页", systemImage: "house")
                }
            
            SearchView()
                .tabItem {
                    Label("搜索", systemImage: "magnifyingglass")
                }
            
            ProfileView()
                .tabItem {
                    Label("我的", systemImage: "person")
                }
        }
    }
}

6. 复杂导航示例

带导航栏的完整示例

swift 复制代码
struct MainView: View {
    @State private var navigationPath = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $navigationPath) {
            ProductListView()
                .navigationTitle("产品列表")
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button("设置") {
                            navigationPath.append(AppRoute.settings)
                        }
                    }
                }
                .navigationDestination(for: AppRoute.self) { route in
                    route.destination
                }
        }
    }
}

enum AppRoute: Hashable {
    case productDetail(Product)
    case category(String)
    case settings
    case profile
    
    @ViewBuilder
    var destination: some View {
        switch self {
        case .productDetail(let product):
            ProductDetailView(product: product)
        case .category(let category):
            CategoryView(category: category)
        case .settings:
            SettingsView()
        case .profile:
            ProfileView()
        }
    }
}

自定义导航栏

swift 复制代码
struct CustomNavigationView: View {
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        NavigationView {
            Text("自定义导航栏")
                .navigationTitle("标题")
                .navigationBarTitleDisplayMode(.inline)
                .toolbar {
                    // 左侧按钮
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button("取消") {
                            dismiss()
                        }
                    }
                    
                    // 右侧按钮
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button("保存") {
                            // 保存操作
                        }
                        .bold()
                    }
                }
        }
    }
}

7. 导航状态管理

swift 复制代码
class NavigationManager: ObservableObject {
    @Published var path = NavigationPath()
    
    func navigateToProduct(_ id: Int) {
        path.append(Route.product(id))
    }
    
    func navigateToCategory(_ name: String) {
        path.append(Route.category(name))
    }
    
    func popToRoot() {
        path.removeLast(path.count)
    }
}

struct AppView: View {
    @StateObject private var navManager = NavigationManager()
    
    var body: some View {
        NavigationStack(path: $navManager.path) {
            ContentView()
                .navigationDestination(for: Route.self) { route in
                    // 路由处理
                }
        }
        .environmentObject(navManager)
    }
}

主要特点总结

  1. NavigationStack: iOS 16+ 推荐使用,支持类型安全的路由
  2. 编程式导航: 通过状态管理控制导航流程
  3. 模态展示: Sheet 和 FullScreenCover 用于临时内容
  4. 标签导航: TabView 用于主要功能模块切换
  5. 灵活的路由系统: 支持复杂导航逻辑和深度链接

这些导航方式可以组合使用,创建出符合你应用需求的完整导航体验。

相关推荐
zero15972 分钟前
TypeScript 快速实战系列:函数进阶|TypeScript 函数 + 异步:大模型 API 调用核心
前端·typescript·大模型编程语言
無名路人4 分钟前
用 codex AI 更新了下之前写的浏览器云书签标签页扩展
前端·openai·ai编程
月弦笙音9 分钟前
【pnpm 】pnpm 执行 xxx 的 底层原理
前端
Devin_chen30 分钟前
单例模式渐进式学习指南
前端·javascript
苏西的网络日志43 分钟前
基于 Element Plus 的企业级主题定制方案:SCSS 变量覆盖 + Vite 全局注入实战
前端
吴声子夜歌1 小时前
Vue3——计算属性和监听属性
前端·vue.js
苏西的网络日志1 小时前
小程序 web-view 内嵌 H5 的会话管理:Token 失效跳转登录的完整方案
前端
小满zs1 小时前
Next.js精通SEO第一章(引言)
前端·seo·next.js
Joyee6911 小时前
RN 的新模块系统 Turbo module
前端·react native
阿民_armin1 小时前
使用 IntersectionObserver + 哨兵元素实现长列表懒加载
前端·javascript·vue.js