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

iOS 16中SwiftUI的NavigationStack与TabView:Bug还是用法不当?

解决NavigationStack嵌套TabView时Tab2滚动导航标题不收缩的问题

环境:Xcode 14.1、iOS 16.1

问题描述

实现了NavigationStack嵌套TabView的结构,TabView包含两个带ScrollView的页面:

  • 点击Tab1后上滑,大导航标题正常居中收缩,页面内容滑至下方并模糊,符合预期;
  • 点击Tab2后上滑,大标题无变化,页面内容也不会模糊;切回Tab1后恢复正常。

原代码

ContentView

import SwiftUI

struct ContentView: View {
   
   @State private var selection: Tab = .tab1
   enum Tab {
      case tab1
      case tab2
   }
   @State private var mainTitle = "Tab1"
   
    var body: some View {
        
       NavigationStack {
          
          TabView(selection: $selection) {
             
             Tab1(mainTitle: $mainTitle)
                 .tabItem {
                     Label("Tab1", systemImage: "wrench.adjustable.fill")
                 }
                 .tag(Tab.tab1)
             
             Tab2(mainTitle: $mainTitle)
                 .tabItem {
                     Label("Tab2", systemImage: "wrench.adjustable.fill")
                 }
                 .tag(Tab.tab2)
             
          } .navigationTitle(mainTitle)
          
       }
       
    }
}

Tab1

import SwiftUI

struct Tab1: View {
   @Binding var mainTitle : String
   
    var body: some View {
       ScrollView {

          Text("Text tab 1")
             .padding(.all,100)
             .background(.blue)
       } .onAppear {
          mainTitle = "Tab1"
       }
    }
}

Tab2

import SwiftUI

struct Tab2: View {
   @Binding var mainTitle : String
   
    var body: some View {
       ScrollView {

          Text("Text tab 2")
             .padding(.all,100)
             .background(.green)
       } .onAppear {
          mainTitle = "Tab2"
       }
    }
}

尝试过的无效方案

.onAppear {
    let tabBarAppearance = UITabBarAppearance()
    tabBarAppearance.configureWithOpaqueBackground()
    UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance
}

解决方案

问题根源是外层NavigationStack无法在Tab切换时,自动将导航栏的滚动联动关联到新Tab的ScrollView。将NavigationStack移至每个Tab内部,让每个页面拥有独立的导航上下文,即可解决该问题:

修改后的ContentView

import SwiftUI

struct ContentView: View {
    @State private var selection: Tab = .tab1
    enum Tab {
        case tab1
        case tab2
    }
    
    var body: some View {
        TabView(selection: $selection) {
            // Tab1独立导航栈
            NavigationStack {
                Tab1()
                    .navigationTitle("Tab1")
            }
            .tabItem {
                Label("Tab1", systemImage: "wrench.adjustable.fill")
            }
            .tag(Tab.tab1)
            
            // Tab2独立导航栈
            NavigationStack {
                Tab2()
                    .navigationTitle("Tab2")
            }
            .tabItem {
                Label("Tab2", systemImage: "wrench.adjustable.fill")
            }
            .tag(Tab.tab2)
        }
    }
}

修改后的Tab1

import SwiftUI

struct Tab1: View {
    var body: some View {
        ScrollView {
            Text("Text tab 1")
                .padding(.all,100)
                .background(.blue)
        }
    }
}

修改后的Tab2

import SwiftUI

struct Tab2: View {
    var body: some View {
        ScrollView {
            Text("Text tab 2")
                .padding(.all,100)
                .background(.green)
        }
    }
}

此方案让每个Tab页面的ScrollView与自身的NavigationStack绑定,切换Tab时导航栏的滚动联动会正常触发,标题收缩、内容模糊的效果均能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:40:24