Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: Hide Statusbar on NavigationLink destination

Tags:

swiftui

I have a master detail structure with a list on master and a detail page where I want to present a webpage fullscreen, so no navigation bar and no status bar. The user can navigate back by a gesture (internal app).

I'm stuggeling hiding the statusbar with

.statusBar(hidden: true)

This works on master page, but not on detail page.

Hiding the navigation bar works fine with my 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())
    }
}

Any idea?

like image 486
netshark1000 Avatar asked Jan 01 '23 06:01

netshark1000


1 Answers

I've been trying this for a couple of hours out of curiosity. At last, I've got it working.

The trick is to hide the status bar in the Main view, whenever the user navigates to the detail view. Here's the code tested in iPhone 11 Pro Max - 13.3 and Xcode version 11.3.1. Hope you like it ;). Happy coding.

Main View Detail View

import SwiftUI
import UIKit
import WebKit

struct ContentView: View {
    var urls: [String] = ["https://www.stackoverflow.com", "https://www.yahoo.com"]
    @State private var hideStatusBar = false

    var body: some View {
        NavigationView {
            List {
                ForEach(urls, id: \.self) { url in
                    VStack {
                        NavigationLink(destination: DetailView(url: url)) {
                            Text(url)
                        }
                        .onDisappear() {
                            self.hideStatusBar = true
                        }
                        .onAppear() {
                            self.hideStatusBar = false
                        }
                    }
                }
            }
            .navigationBarTitle("Main")
        }
        .statusBar(hidden: hideStatusBar)
    }
}

struct DetailView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var url: String = ""

    var body: some View {
        VStack {
            Webview(url: url)
            Button("Tap to go back.") {
                self.presentationMode.wrappedValue.dismiss()
            }
            Spacer()
        }
        .hideNavigationAndStatusBar()
    }
}

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}
    }
}

struct Webview: UIViewRepresentable {
    var url: String
    typealias UIViewType = WKWebView

    func makeUIView(context: UIViewRepresentableContext<Webview>) -> WKWebView {
        let wkWebView = WKWebView()
        guard let url = URL(string: self.url) else {
            return wkWebView
        }

        let request = URLRequest(url: url)
        wkWebView.load(request)
        return wkWebView
    }

    func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<Webview>) {
    }
}

extension View {
    public func hideNavigationAndStatusBar() -> some View {
        modifier(NavigationAndStatusBarHider())
    }
}
like image 53
Felix Marianayagam Avatar answered Apr 27 '23 04:04

Felix Marianayagam