SwiftUI:隐藏NavigationLink目标上的状态栏

SwiftUI:隐藏NavigationLink目标上的状态栏,swiftui,Swiftui,我有一个主-详细结构,在主上有一个列表和一个详细页面,在那里我想全屏显示一个网页,所以没有导航栏和状态栏。用户可以通过手势向后导航(内部应用程序) 我在用它隐藏状态栏 .statusBar(hidden: true) 这适用于母版页,但不适用于详细页 隐藏导航栏可以与我的ViewModifier配合使用 public struct NavigationAndStatusBarHider: ViewModifier { @State var isHidden: Bool = false

我有一个主-详细结构,在主上有一个列表和一个详细页面,在那里我想全屏显示一个网页,所以没有导航栏和状态栏。用户可以通过手势向后导航(内部应用程序)

我在用它隐藏状态栏

.statusBar(hidden: true)
这适用于母版页,但不适用于详细页

隐藏导航栏可以与我的ViewModifier配合使用

public struct NavigationAndStatusBarHider: ViewModifier {
    @State var isHidden: Bool = false

    public func body(content: Content) -> some View {
        content
            .navigationBarTitle("")
            .navigationBarHidden(isHidden)
            .statusBar(hidden: isHidden)
            .onAppear {self.isHidden = true}
    }
}

extension View {
    public func hideNavigationAndStatusBar() -> some View {
        modifier(NavigationAndStatusBarHider())
    }
}

有什么想法吗?

好吧,你观察到的行为是因为状态栏隐藏在
NavigationView
内部调用时不起作用,但在外部起作用。使用Xcode 11.2和(!)Xcode 11.4beta3进行测试

请看下面我的发现

案例1:任何堆叠容器内

案例2:内部
NavigationView

在导航视图之外使用
.statusBar(隐藏:)
的解决方案(修复/解决方法)。因此,您应该相应地更新修改器(或重新考虑设计以将其分离)


出于好奇,我已经试了几个小时了。我终于让它工作了

诀窍是在用户导航到详细视图时,在主视图中隐藏状态栏。以下是在iPhone11Pro Max-13.3和Xcode版本11.3.1中测试的代码。希望你喜欢。快乐编码

导入快捷界面
导入UIKit
导入WebKit
结构ContentView:View{
变量URL:[字符串]=[”https://www.stackoverflow.com", "https://www.yahoo.com"]
@状态私有变量hideStatusBar=false
var body:一些观点{
导航视图{
名单{
ForEach(url,id:\.self){url在
VStack{
导航链接(目的地:详细视图(url:url)){
文本(url)
}
.onDisappear(){
self.hideStatusBar=true
}
.onAppear(){
self.hideStatusBar=false
}
}
}
}
.navigationBarTitle(“主要”)
}
.statusBar(隐藏:hideStatusBar)
}
}
结构详细视图:视图{
@环境(\.presentationMode)变量presentationMode:绑定
var url:String=“”
var body:一些观点{
VStack{
网络视图(url:url)
按钮(“点击返回”){
self.presentationMode.wrappedValue.discouse()文件
}
垫片()
}
.hideNavigationAndStatusBar()
}
}
公共结构NavigationAndStatusBarHider:ViewModifier{
@状态变量isHidden:Bool=false
公共函数体(内容:content)->一些视图{
内容
.navigationBarTitle(“”)
.navigationBarHidden(isHidden)
.statusBar(隐藏:isHidden)
.onAppear{self.ishiden=true}
}
}
结构Webview:UIViewRepresentable{
var url:String
typealias UIViewType=WKWebView
func makeUIView(上下文:UIViewRepresentableContext)->WKWebView{
设wkWebView=wkWebView()
guard let url=url(字符串:self.url)else{
返回wkWebView
}
let request=URLRequest(url:url)
wkWebView.load(请求)
返回wkWebView
}
func updateUIView(uiView:WKWebView,context:UIViewRepresentableContext){
}
}
扩展视图{
public func hideNavigationAndStatusBar()->一些视图{
修饰符(NavigationAndStatusBarHider())
}
}

我有一个
导航视图
,其中包含一个显示
全屏模式的视图。我希望状态栏在
导航视图中可见,但在
全屏模式中隐藏。我尝试了多种方法,但都没有成功(似乎很多人在iOS14上发现了状态栏和
NavigationView
的bug)

我已经确定了一个解决方案,这是黑客,但似乎工作,应该做的工作,直到错误被修复

将以下内容添加到您的
Info.plist

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

它会给您一个不推荐使用的警告,但我希望这是一个临时修复。

针对Xcode 12.5和IOS 14.6的解决方案:

将以下内容添加到您的
Info.plist

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
然后,您可以使用
UIApplication.shared.isStatusBarHidden
修改器隐藏并带回应用程序中的任何位置的状态栏

例如:

struct Example: View {
    
    // I'm checking the safe area below the viewport 
    // to be able to detect iPhone models without a notch.
    @State private var bottomSafeArea = UIApplication.shared.windows.first?.safeAreaInsets.bottom
    
    var body: some View {
        
          Button {
              if bottomSafeArea == 0 {
                  UIApplication.shared.isStatusBarHidden = true // or use .toggle()
              }
          } label: {
              Text("Click here for hide status bar!")
                  .font(.title2)
        }
    }
}

好的-但是我的详细视图没有NavigationView。ZStack是父母。但是它当然是生活在NavigationViewBy inside我的意思是在任何级别的内部这些设置会覆盖plist值(比如UIStatusBarHidden)还是plist值优先,需要删除才能工作?
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        UIApplication.shared.isStatusBarHidden = false // -> This

        return true
    }
struct Example: View {
    
    // I'm checking the safe area below the viewport 
    // to be able to detect iPhone models without a notch.
    @State private var bottomSafeArea = UIApplication.shared.windows.first?.safeAreaInsets.bottom
    
    var body: some View {
        
          Button {
              if bottomSafeArea == 0 {
                  UIApplication.shared.isStatusBarHidden = true // or use .toggle()
              }
          } label: {
              Text("Click here for hide status bar!")
                  .font(.title2)
        }
    }
}