Jestem nowy w SwiftUI (jak większość ludzi) i próbuję dowiedzieć się, jak usunąć niektóre białe znaki nad listą, którą osadziłem w NavigationView
Na tym obrazku widać, że nad listą znajduje się spacja
To, co chcę osiągnąć, to to
Próbowałem użyć
.navigationBarHidden(true)
ale to nie spowodowało żadnych zauważalnych zmian.
Obecnie konfiguruję mój NavigiationView w ten sposób
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarHidden(true)
}
gdzie FileBrowserView to widok z listą i komórkami zdefiniowanymi w ten sposób
List {
Section(header: Text("Root")){
FileCell(name: "Test", fileType: "JPG",fileDesc: "Test number 1")
FileCell(name: "Test 2", fileType: "txt",fileDesc: "Test number 2")
FileCell(name: "test3", fileType: "fasta", fileDesc: "")
}
}
Chcę zauważyć, że ostatecznym celem jest tutaj to, że będziesz w stanie kliknąć te komórki, aby przejść głębiej do drzewa plików, a zatem powinien wyświetlić przycisk Wstecz na pasku podczas głębszej nawigacji, ale nie chcę niczego w top jako taki podczas mojego pierwszego widoku.
źródło
navigationBarHidden
dofalse
następnego widoku powinien odkryć pasek nawigacji, ale tak nie jest. Ostatecznie miałem dość tego, jak słabo udokumentowany był SwiftUI i wróciłem do UIKit, a fakt, że co najmniej 20 osób przybyło tutaj tylko po to, aby dowiedzieć się, jak ukryć pasek nawigacji, mówi dość słabo o implementacji i / lub dokumentacji Apple. Przepraszam, nie mam dla ciebie lepszej odpowiedzi.Celem a
NavigationView
jest dodanie paska nawigacyjnego u góry widoku. W iOS dostępne są 2 rodzaje pasków nawigacyjnych: duże i standardowe.Jeśli nie chcesz paska nawigacji:
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
Jeśli chcesz mieć duży pasek nawigacyjny (zwykle używany w widokach najwyższego poziomu):
NavigationView { FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL)) .navigationBarTitle(Text("Title")) }
Jeśli chcesz mieć standardowy (wbudowany) pasek nawigacji (zwykle używany w widokach podpoziomów):
NavigationView { FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL)) .navigationBarTitle(Text("Title"), displayMode: .inline) }
Mam nadzieję, że ta odpowiedź ci pomoże.
Więcej informacji: Dokumentacja Apple
źródło
NavigationView
. Celem aNavigationView
nie jest wyłącznie wyświetlanie paska nawigacji.Zobacz modyfikatory ułatwiające:
//ViewModifiers.swift struct HiddenNavigationBar: ViewModifier { func body(content: Content) -> some View { content .navigationBarTitle("", displayMode: .inline) .navigationBarHidden(true) } } extension View { func hiddenNavigationBarStyle() -> some View { modifier( HiddenNavigationBar() ) } }
Przykład:
import SwiftUI struct MyView: View { var body: some View { NavigationView { VStack { Spacer() HStack { Spacer() Text("Hello World!") Spacer() } Spacer() } .padding() .background(Color.green) //remove the default Navigation Bar space: .hiddenNavigationBarStyle() } } }
źródło
Jeśli ustawisz tytuł jako wbudowany dla widoku, w którym chcesz usunąć spację, nie trzeba tego robić w widoku z NavigationView, ale również nawigowanym.
.navigationBarTitle("", displayMode: .inline)
następnie po prostu zmień wygląd pasków nawigacji
init() { UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default) UINavigationBar.appearance().shadowImage = UIImage() }
w widoku, który zawiera początkową NavigationView.
Jeśli chcesz zmienić wygląd z ekranu na ekran, zmień wygląd w odpowiednich widokach
źródło
Wypróbowałem również wszystkie rozwiązania wymienione na tej stronie i uznałem, że rozwiązanie @graycampbell działa dobrze, z dobrze działającymi animacjami. Próbowałem więc stworzyć wartość, której mogę po prostu używać w całej aplikacji, do której mam dostęp w dowolnym miejscu na przykładzie hackingwithswift.com
Stworzyłem
ObservableObject
klasęclass NavBarPreferences: ObservableObject { @Published var navBarIsHidden = true }
I w
SceneDelegate
podobny sposób przejdź do widoku początkowegovar navBarPreferences = NavBarPreferences() window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(navBarPreferences))
Następnie
ContentView
możemy śledzić ten obiekt obserwowalny w ten sposób i utworzyć łącze doSomeView
:struct ContentView: View { //This variable listens to the ObservableObject class @EnvironmentObject var navBarPrefs: NavBarPreferences var body: some View { NavigationView { NavigationLink ( destination: SomeView()) { VStack{ Text("Hello first screen") .multilineTextAlignment(.center) .accentColor(.black) } } .navigationBarTitle(Text(""),displayMode: .inline) .navigationBarHidden(navBarPrefs.navBarIsHidden) .onAppear{ self.navBarPrefs.navBarIsHidden = true } } } }
A potem, uzyskując dostęp do drugiego widoku (SomeView), ponownie go ukrywamy w ten sposób:
struct SomeView: View { @EnvironmentObject var navBarPrefs: NavBarPreferences var body: some View { Text("Hello second screen") .onAppear { self.navBarPrefs.navBarIsHidden = false } } }
Aby podglądy działały, dodaj NavBarPreferences do podglądu w następujący sposób:
struct SomeView_Previews: PreviewProvider { static var previews: some View { SomeView().environmentObject(NavBarPreferences()) } }
źródło
Jest to błąd występujący w SwiftUI ( nadal w Xcode 11.2.1). Napisałem,
ViewModifier
aby to naprawić, na podstawie kodu z istniejących odpowiedzi:public struct NavigationBarHider: ViewModifier { @State var isHidden: Bool = false public func body(content: Content) -> some View { content .navigationBarTitle("") .navigationBarHidden(isHidden) .onAppear { self.isHidden = true } } } extension View { public func hideNavigationBar() -> some View { modifier(NavigationBarHider()) } }
źródło
Możesz rozszerzyć natywny protokół View w następujący sposób:
extension View { func hideNavigationBar() -> some View { self .navigationBarTitle("", displayMode: .inline) .navigationBarHidden(true) } }
Następnie zadzwoń np .:
ZStack { *YOUR CONTENT* } .hideNavigationBar()
źródło
Dla mnie, ja stosujące
.navigationBarTitle
się doNavigationView
i nieList
był winowajcą. To działa dla mnie na Xcode 11.2.1:struct ContentView: View { var body: some View { NavigationView { List { NavigationLink(destination: DetailView()) { Text("I'm a cell") } }.navigationBarTitle("Title", displayMode: .inline) } } }
źródło
Dla mnie było to spowodowane wypychaniem mojego NavigationView z istniejącego. W efekcie jedno w drugim. Jeśli pochodzisz z NavigationView, nie musisz tworzyć jednego wewnątrz następnego, ponieważ jesteś już w NavigatonView.
źródło
Podobna do odpowiedzi @graycampbell, ale trochę prostsza:
struct YourView: View { @State private var isNavigationBarHidden = true var body: some View { NavigationView { VStack { Text("This is the master view") NavigationLink("Details", destination: Text("These are the details")) } .navigationBarHidden(isNavigationBarHidden) .navigationBarTitle("Master") .onAppear { self.isNavigationBarHidden = true } .onDisappear { self.isNavigationBarHidden = false } } } }
Ustawienie tytułu jest konieczne, ponieważ w przeglądanych widokach jest on wyświetlany obok przycisku Wstecz.
źródło
SwiftUI 2
Istnieje specjalny modyfikator, który sprawia, że pasek nawigacji zajmuje mniej miejsca:
Nie trzeba już ukrywać paska nawigacji ani ustawiać jego tytułu.
źródło
Naprawdę podobał mi się pomysł podany przez @Vatsal Manot Aby stworzyć modyfikator do tego.
Usunięcie
isHidden
właściwości z jego odpowiedzi, ponieważ nie wydaje mi się to przydatne, ponieważ sama nazwa modyfikatora sugeruje ukrywanie paska nawigacji.// Hide navigation bar. public struct NavigationBarHider: ViewModifier { public func body(content: Content) -> some View { content .navigationBarTitle("") .navigationBarHidden(true) } } extension View { public func hideNavigationBar() -> some View { modifier(NavigationBarHider()) } }
źródło
Miałem podobny problem podczas pracy nad aplikacją, w której TabView powinien być wyświetlany po zalogowaniu się użytkownika.
Jak zasugerował @graycampbell w swoim komentarzu, TabView nie powinien być osadzany w NavigationView, w przeciwnym razie pojawi się „puste miejsce”, nawet jeśli używasz
.navigationBarHidden(true)
Użyłem,
ZStack
aby ukryć NavigationView. Zauważ, że w tym prostym przykładzie używam@State
i@Binding
do zarządzania widocznością interfejsu użytkownika, ale możesz chcieć użyć czegoś bardziej złożonego, takiego jak obiekt środowiska.struct ContentView: View { @State var isHidden = false var body: some View { ZStack { if isHidden { DetailView(isHidden: self.$isHidden) } else { NavigationView { Button("Log in"){ self.isHidden.toggle() } .navigationBarTitle("Login Page") } } } } }
Po naciśnięciu przycisku Zaloguj się strona początkowa znika i ładowany jest widok DetailView. Strona logowania pojawia się ponownie po przełączeniu przycisku Wyloguj
struct DetailView: View { @Binding var isHidden: Bool var body: some View { TabView{ NavigationView { Button("Log out"){ self.isHidden.toggle() } .navigationBarTitle("Home") } .tabItem { Image(systemName: "star") Text("One") } } } }
źródło
Moje rozwiązanie tego problemu było takie samo, jak sugerowane przez @Genki i @Frankenstein.
Zastosowałem dwa modyfikatory do wewnętrznej listy (NIE NavigationView), aby pozbyć się odstępów:
.navigationBarTitle("", displayMode: .automatic) .navigationBarHidden(true)
Na zewnętrznym NavigationView, a następnie zastosowany
.navigationBarTitle("TITLE")
do ustawienia tytułu.źródło
Spróbuj
NavigationView
włożyć do środkaGeometryReader
.GeometryReader { NavigationView { Text("Hello World!") } }
Doświadczyłem dziwnego zachowania, gdy
NavigationView
był to widok główny.źródło