导航
问题
SwiftUI 中有哪些导航方式?NavigationStack 和 NavigationView 有什么区别?
答案
NavigationStack(iOS 16+)
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
List(items) { item in
NavigationLink(value: item) {
Text(item.title)
}
}
.navigationTitle("Items")
.navigationDestination(for: Item.self) { item in
DetailView(item: item)
}
}
}
// 程序化导航
func navigateToDetail(_ item: Item) {
path.append(item)
}
func popToRoot() {
path = NavigationPath()
}
}
Sheet(模态)
struct ParentView: View {
@State private var showSheet = false
@State private var showFullScreen = false
var body: some View {
VStack {
Button("Show Sheet") { showSheet = true }
Button("Show Full Screen") { showFullScreen = true }
}
.sheet(isPresented: $showSheet) {
SheetView()
}
.fullScreenCover(isPresented: $showFullScreen) {
FullScreenView()
}
}
}
TabView
struct MainTabView: View {
@State private var selectedTab = 0
var body: some View {
TabView(selection: $selectedTab) {
HomeView()
.tabItem {
Label("Home", systemImage: "house")
}
.tag(0)
ProfileView()
.tabItem {
Label("Profile", systemImage: "person")
}
.tag(1)
}
}
}
NavigationView(旧) vs NavigationStack(新)
| NavigationView | NavigationStack | |
|---|---|---|
| 最低版本 | iOS 13 | iOS 16 |
| 程序化导航 | 困难(isActive) | 简单(path 绑定) |
| Deep Link | 复杂 | 原生支持 |
| 类型安全 | 弱 | 强 |
常见面试问题
Q1: 如何在 SwiftUI 中实现 Deep Link 导航?
答案:iOS 16+ 使用 NavigationStack + NavigationPath,将路径序列化:
@State private var path = NavigationPath()
// 收到 Deep Link
func handleDeepLink(_ url: URL) {
if let item = parseItem(from: url) {
path.append(item)
}
}
Q2: sheet 和 fullScreenCover 的区别?
sheet:卡片式呈现,可下拉关闭,底部 VC 可见fullScreenCover:全屏覆盖,必须手动关闭