SwiftUI: Скрыть строку состояния в пункте назначения NavigationLink - PullRequest
2 голосов
/ 12 марта 2020

У меня есть основная структура сведений со списком на главной странице и страницей сведений, где я хочу представить веб-страницу в полноэкранном режиме, поэтому нет панели навигации и строки состояния. Пользователь может вернуться назад жестом (внутреннее приложение).

Я скрываю строку состояния с помощью

.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())
    }
}

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 12 марта 2020

Я пытался это пару часов из любопытства. Наконец-то у меня все получилось.

Хитрость заключается в том, чтобы скрыть строку состояния в главном представлении всякий раз, когда пользователь переходит к подробному виду. Вот код, протестированный в iPhone 11 Pro Max - 13.3 и Xcode версии 11.3.1. Надеюсь, вам понравится;). Удачного кодирования.

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())
    }
}
1 голос
/ 12 марта 2020

Что ж, вы наблюдаете за тем, что скрытие строки состояния не работает при вызове изнутри NavigationView, а работает снаружи. Протестировано с Xcode 11.2 и (!) Xcode 11.4beta3.

Пожалуйста, смотрите ниже мои выводы.

demo1 demo2

          Case1                         Case2

Case1: Внутри любого стекового контейнера

struct TestNavigationWithStatusBar: View {
    var body: some View {
        VStack {
            Text("Hello, World!")
                .statusBar(hidden: true)
        }
    }
}

Case2: Внутри NavigationView

struct TestNavigationWithStatusBar: View {
    var body: some View {
        NavigationView {
            Text("Hello, World!")
                .statusBar(hidden: true)
        }
    }
}

Решение (исправить / обойти) для использования .statusBar(hidden:) снаружи навигационного представления. Таким образом, вы должны соответствующим образом обновить свой модификатор (или переосмыслить дизайн, чтобы отделить его).

demo3

struct TestNavigationWithStatusBar: View {
    var body: some View {
        NavigationView {
            Text("Hello, World!")
        }
        .statusBar(hidden: true)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...