Soy nuevo en SwiftUI (como la mayoría de las personas) y trato de descubrir cómo eliminar algunos espacios en blanco sobre una lista que incrusté en un NavigationView
En esta imagen, puede ver que hay un espacio en blanco sobre la Lista
Lo que quiero lograr es esto
He intentado usar
.navigationBarHidden(true)
pero esto no hizo cambios notables.
Actualmente estoy configurando mi navigiationView así
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarHidden(true)
}
donde FileBrowserView es una vista con una lista y celdas definidas así
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: "")
}
}
Quiero señalar que el objetivo final aquí es que podrá hacer clic en estas celdas para navegar más profundamente en un árbol de archivos y, por lo tanto, debería mostrar un botón Atrás en la barra de navegación más profunda, pero no quiero nada en el top como tal durante mi vista inicial.
fuente
navigationBarHidden
defalse
la siguiente vista debe mostrar la barra de navegación, pero no es así. Finalmente, me cansé de lo mal documentado que estaba SwiftUI y volví a UIKit, y el hecho de que al menos 20 personas vinieran aquí solo para aprender a ocultar la barra de navegación habla bastante mal de la implementación y / o documentación de Apple. Lo siento, no tengo una mejor respuesta para ti.El propósito de a
NavigationView
es agregar la barra de navegación en la parte superior de su vista. En iOS, hay 2 tipos de barras de navegación: grandes y estándar.Si no desea una barra de navegación:
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
Si desea una barra de navegación grande (generalmente se usa para sus vistas de nivel superior):
NavigationView { FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL)) .navigationBarTitle(Text("Title")) }
Si desea una barra de navegación estándar (en línea) (generalmente se usa para vistas de subnivel):
NavigationView { FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL)) .navigationBarTitle(Text("Title"), displayMode: .inline) }
Espero que esta respuesta te ayude.
Más información: Documentación de Apple
fuente
NavigationView
. El propósito de aNavigationView
no es únicamente mostrar una barra de navegación.Ver modificadores lo hizo fácil:
//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() ) } }
Ejemplo:
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() } } }
fuente
También probé todas las soluciones mencionadas en esta página y solo encontré la solución @graycampbell que funciona bien, con animaciones que funcionan bien. Así que traté de crear un valor que pueda usar en toda la aplicación al que pueda acceder desde cualquier lugar con el ejemplo de hackingwithswift.com
Creé una
ObservableObject
claseclass NavBarPreferences: ObservableObject { @Published var navBarIsHidden = true }
Y pasarlo a la vista inicial de la
SceneDelegate
misma maneravar navBarPreferences = NavBarPreferences() window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(navBarPreferences))
Luego, en el
ContentView
podemos realizar un seguimiento de este objeto observable y crear un enlace aSomeView
: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 } } } }
Y luego al acceder a la segunda vista (SomeView), la volvemos a ocultar así:
struct SomeView: View { @EnvironmentObject var navBarPrefs: NavBarPreferences var body: some View { Text("Hello second screen") .onAppear { self.navBarPrefs.navBarIsHidden = false } } }
Para que las vistas previas sigan funcionando, agregue NavBarPreferences a la vista previa de la siguiente manera:
struct SomeView_Previews: PreviewProvider { static var previews: some View { SomeView().environmentObject(NavBarPreferences()) } }
fuente
Este es un error presente en SwiftUI ( aún a partir de Xcode 11.2.1). Escribí un
ViewModifier
para solucionar esto, basado en el código de las respuestas existentes: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()) } }
fuente
Si configura el título como en línea para la Vista en la que desea eliminar el espacio, no es necesario hacerlo en una vista con NavigationView, sino también en la vista navegada.
.navigationBarTitle("", displayMode: .inline)
luego simplemente cambie la apariencia de las barras de navegación
init() { UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default) UINavigationBar.appearance().shadowImage = UIImage() }
en la vista que contiene el NavigationView inicial.
Si desea cambiar la apariencia de una pantalla a otra, cambie la apariencia en las vistas apropiadas
fuente
Puede extender el protocolo de vista nativo de esta manera:
extension View { func hideNavigationBar() -> some View { self .navigationBarTitle("", displayMode: .inline) .navigationBarHidden(true) } }
Entonces solo llame por ejemplo:
ZStack { *YOUR CONTENT* } .hideNavigationBar()
fuente
Para mí, estaba aplicando el
.navigationBarTitle
alNavigationView
y noList
el culpable. Esto me funciona en 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) } } }
fuente
Similar a la respuesta de @graycampbell pero un poco más 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 } } } }
Es necesario establecer el título, ya que se muestra junto al botón Atrás en las vistas a las que navega.
fuente
Para mí fue porque estaba empujando mi NavigationView desde un archivo. En efecto, tener uno dentro del otro. Si viene de un NavigationView, no necesita crear uno dentro del siguiente, ya que ya está dentro de un NavigatonView.
fuente
Realmente me encantó la idea de @Vatsal Manot de crear un modificador para esto.
Eliminar la
isHidden
propiedad de su respuesta, ya que no lo encuentro útil, ya que el nombre del modificador sugiere que oculta la barra de navegación.// 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()) } }
fuente
Tuve un problema similar al trabajar en una aplicación donde debería mostrarse un TabView una vez que el usuario inició sesión.
Como sugirió @graycampbell en su comentario, un TabView no debe estar incrustado en un NavigationView, o de lo contrario aparecerá el "espacio en blanco", incluso cuando se usa
.navigationBarHidden(true)
Usé un
ZStack
para ocultar NavigationView. Tenga en cuenta que para este ejemplo simple, utilizo@State
y@Binding
para administrar la visibilidad de la interfaz de usuario, pero es posible que desee usar algo más complejo, como un objeto de entorno.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") } } } } }
Cuando presionamos el botón Iniciar sesión, la página inicial desaparece y se carga DetailView. La página de inicio de sesión vuelve a aparecer cuando cambiamos el botón Cerrar sesión
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") } } } }
fuente
Mi solución para este problema fue la misma que sugirieron @Genki y @Frankenstein.
Apliqué dos modificadores a la lista interna (NO al NavigationView) para deshacerme del espaciado:
.navigationBarTitle("", displayMode: .automatic) .navigationBarHidden(true)
En el NavigationView exterior, luego se aplica
.navigationBarTitle("TITLE")
para establecer el título.fuente
SwiftUI 2
Hay un modificador dedicado para hacer que la barra de navegación ocupe menos espacio:
Ya no es necesario ocultar la barra de navegación ni establecer su título.
fuente
Intente poner el
NavigationView
interior aGeometryReader
.GeometryReader { NavigationView { Text("Hello World!") } }
Experimenté un comportamiento extraño cuando
NavigationView
era la vista raíz.fuente