NavigationTitle 视觉故障 - 透明且不会在滚动时将状态从 .large 更改为 .inline

NavigationTitle visual glitches - transparent and not changing state from .large to .inline on scroll

.navigationTitle在某些视图上似乎有一些问题。在某些视图中(并且只是在某些时候),.navigationTitle 不会像预期的那样从 .large 更改为 .inline。取而代之的是,向上滚动时标题会保留在原位,并且导航栏完全不可见(如下面的视频所述)。这每次都是可重现的。

Video of reproducible .navigationTitle bugs

我在 stack overflow 或 Apple Developer 论坛上没有发现任何人 运行 对这个确切问题有任何了解。有些人产生了与此类似的结果,但这些都是通过删除 .navigationbar 中的一些样式化代码来修复的,我没有在我的代码中的任何地方对其进行任何修改。

下面是我的一些代码片段:

import SwiftUI
struct WelcomeUI: View { 
   var body: some View {
      NavigationView {
         VStack {
            //NavigationLink(destination: SignupUI(), label: {
               //Text("Sign Up")
            //}
            NavigationLink(destination: LoginUI(), label: {
               Text("Log In")
            })
         }
      }
   }
}


struct LoginUI: View {
   var body: some View {
      VStack {
         
         NavigationLink(destination: MainUI(), label: { Text("Log In") })
         //Button(action: { ... }
      }
   .navigationBarHidden(false)
   }
}


struct MainUI: View {
    @State var selectedTab: Views = .add
    var body: some View {
        
        TabView(selection: $selectedTab) {
            SpendingView()
                .tabItem {
                    Image(systemName: "bag.circle")
                    Text("Spending")
                }.tag(Views.spending)
            Text("Adding View")
                .tabItem {
                    Image(systemName: "plus")
                    Text("Add")
                }.tag(Views.add)
            Text("Edit View")
                .tabItem {
                    Image(systemName: "pencil")
                    Text("Edit")
                }.tag(Views.edit)
            SettingsView()
                .tabItem {
                    Image(systemName: "gear")
                    Text("Settings")
                }.tag(Views.settings)
        }
        .navigationBarTitle(Text(selectedTab.rawValue))
        .navigationBarBackButtonHidden(true)
    }
}


enum Views: String {
    case spending = "Spending"
    case add = "Add"
    case edit = "Edit"
    case settings = "Settings"
}


struct SettingsView: View {
    var body: some View {
        VStack{
            ZStack {
                Form {
                    Section(header: Text("Section Header")) {
                        NavigationLink(destination: WelcomeUI()) {
                            Text("Setting Option")
                        }
                    }
                    Section {
                        //Button("Log Out") {
                        //self.logout()
                        //}
                        Text("Log Out")
                    }
                }
                Button("say-high", action: {print("Hi")})
            }
        }
    }
}

struct SpendingView: View {
    var body: some View {
        ScrollView{
            Text("SpendingView")
            NavigationLink("subSpending", destination: SubSpendingView())
        }.padding()
    }
}
struct SubSpendingView: View {
    var body: some View {
        ScrollView{
            Text("SubSpendingView")
            
        }.navigationBarTitle("SubSpending")
    }
}

它几乎看起来像是 SwiftUI 本身的一个错误,只是因为关闭控制中心这一事实使其可以正常工作,但没有动画(如视频中所示)。此外,更改 @State var selectedTab: Views 中首先选择的视图似乎让所选视图按预期工作,但让其余选项卡混乱。

当我在我的 iPad 上构建和 运行 应用程序时,它的行为符合预期,没有错误,只有当 运行 在我的 iPhone 上并且 iOS Mac 上的模拟器就是这样做的,有什么办法可以解决这个问题吗?

为了完美地工作,ScrollView 需要是 NavigationView 的直接子级。我 运行 遇到类似的问题,想在导航时关闭 TabView,但 SwiftUI 不会让这种情况发生。每个选项卡都需要是一个 NavigationView,如果需要,您需要创造性地关闭 TabView。

TabView {
    NavigationView {
        ScrollView {
            // your view here
        }
    }.tabItem {
        // tab label
    }
    
    // etc
}

本质上,导航视图需要是选项卡视图的子视图(在括号中),滚动视图需要是导航视图的直接子视图。

在 TabView 的子视图上使用 navigationBarTitle("Title")navigationBarBackButtonHidden(true),而不是在其自身上。

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                
            }
            .navigationBarTitle("Title")
            .navigationBarBackButtonHidden(true)
        }
    }
}