Je suis nouveau sur SwiftUI (comme la plupart des gens) et j'essaie de comprendre comment supprimer des espaces au-dessus d'une liste que j'ai incorporée dans une NavigationView
Dans cette image, vous pouvez voir qu'il y a un espace blanc au-dessus de la liste
Ce que je veux accomplir c'est ceci
J'ai essayé d'utiliser
.navigationBarHidden(true)
mais cela n'a apporté aucun changement notable.
je suis en train de configurer ma navigation
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarHidden(true)
}
où FileBrowserView est une vue avec une liste et des cellules définies comme ceci
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: "")
}
}
Je veux noter que le but ultime ici est que vous serez en mesure de cliquer sur ces cellules pour naviguer plus profondément dans une arborescence de fichiers et donc d'afficher un bouton Retour sur la barre pour une navigation plus approfondie, mais je ne veux rien à la top en tant que tel lors de ma vue initiale.
Pour une raison quelconque, SwiftUI requiert que vous définissiez également .navigationBarTitle
pour .navigationBarHidden
pour fonctionner correctement.
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarTitle("")
.navigationBarHidden(true)
}
Comme @Peacemoon l'a souligné dans les commentaires, la barre de navigation reste masquée lorsque vous naviguez plus profondément dans la pile de navigation, que vous définissiez ou non navigationBarHidden
sur false
dans les vues suivantes. Comme je l'ai dit dans les commentaires, c'est soit le résultat d'une mauvaise mise en œuvre de la part d'Apple, soit simplement une documentation épouvantable (qui sait, il y a peut-être une façon "correcte" d'y parvenir).
Quoi qu'il en soit, j'ai trouvé une solution de contournement qui semble produire les résultats souhaités de l'affiche originale. J'hésite à le recommander car il semble inutilement hacky, mais sans aucun moyen simple de masquer et d'afficher la barre de navigation, c'est le mieux que je puisse faire.
Cet exemple utilise trois vues - View1
possède une barre de navigation masquée et View2
et View3
les deux ont des barres de navigation visibles avec des titres.
struct View1: View {
@State var isNavigationBarHidden: Bool = true
var body: some View {
NavigationView {
ZStack {
Color.red
NavigationLink("View 2", destination: View2(isNavigationBarHidden: self.$isNavigationBarHidden))
}
.navigationBarTitle("Hidden Title")
.navigationBarHidden(self.isNavigationBarHidden)
.onAppear {
self.isNavigationBarHidden = true
}
}
}
}
struct View2: View {
@Binding var isNavigationBarHidden: Bool
var body: some View {
ZStack {
Color.green
NavigationLink("View 3", destination: View3())
}
.navigationBarTitle("Visible Title 1")
.onAppear {
self.isNavigationBarHidden = false
}
}
}
struct View3: View {
var body: some View {
Color.blue
.navigationBarTitle("Visible Title 2")
}
}
La définition de navigationBarHidden
sur false
sur des vues plus profondes dans la pile de navigation ne semble pas remplacer correctement la préférence de la vue qui avait initialement défini navigationBarHidden
sur true
, donc la seule solution de contournement que j'ai pu trouver était d'utiliser une liaison pour changer la préférence de la vue d'origine lorsqu'une nouvelle vue est poussée sur la pile de navigation.
Comme je l'ai dit, c'est une solution hacky, mais sans solution officielle d'Apple, c'est la meilleure que j'ai pu trouver.
Le but d'un NavigationView
est d'ajouter la barre de navigation en haut de votre vue. Dans iOS, il existe 2 types de barres de navigation: grandes et standard.
Si vous ne voulez pas de barre de navigation:
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
Si vous voulez une grande barre de navigation (généralement utilisée pour vos vues de haut niveau):
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarTitle(Text("Title"))
}
Si vous souhaitez une barre de navigation standard (en ligne) (généralement utilisée pour les vues de sous-niveau):
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarTitle(Text("Title"), displayMode: .inline)
}
J'espère que cette réponse vous aidera.
Plus d'informations: Documentation Apple
Il s'agit d'un bogue présent dans SwiftUI (toujours à partir de Xcode 11.2.1). J'ai écrit un ViewModifier
pour résoudre ce problème, basé sur le code des réponses existantes:
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())
}
}
Les modificateurs de vue ont simplifié la tâche:
//ViewModifiers.Swift
struct HiddenNavigationBar: ViewModifier {
func body(content: Content) -> some View {
content
.navigationBarTitle("", displayMode: .inline)
.navigationBarHidden(true)
}
}
extension View {
func hiddenNavigationBarStyle() -> some View {
ModifiedContent(content: self, modifier: HiddenNavigationBar())
}
}
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()
}
}
}
Pour moi, j'appliquais le .navigationBarTitle
au NavigationView
et non au List
était le coupable. Cela fonctionne pour moi sur 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)
}
}
}
Vous pouvez étendre le protocole natif View comme ceci:
extension View {
func hideNavigationBar() -> some View {
self
.navigationBarTitle("", displayMode: .inline)
.navigationBarHidden(true)
}
}
Appelez ensuite par exemple:
ZStack {
*YOUR CONTENT*
}
.hideNavigationBar()
Pour moi, c'était parce que je poussais ma NavigationView à partir d'un existant. En effet, avoir l'un à l'intérieur de l'autre. Si vous venez d'une NavigationView, vous n'avez pas besoin d'en créer une à l'intérieur de la suivante comme vous l'avez déjà à l'intérieur d'une NavigatonView.
Similaire à la réponse de @graycampbell mais un peu plus simple:
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
}
}
}
}
La définition du titre est nécessaire car il est affiché à côté du bouton de retour dans les vues vers lesquelles vous naviguez.
J'ai vraiment adoré l'idée donnée par @ Vatsal Manot Pour créer un modificateur pour cela.
Suppression de la propriété isHidden
de sa réponse, car je ne la trouve pas utile car le nom du modificateur lui-même suggère de masquer la barre de navigation.
// 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())
}
}