Vap*_*ant 13 ios swift swiftui swiftui-list swiftui-bug
我是SwiftUI的新手(就像大多数人一样),试图弄清楚如何删除我在NavigationView中嵌入的List上方的空白。
在此图像中,您可以看到列表上方有一些空白

我要完成的是

我试过使用
.navigationBarHidden(true)
Run Code Online (Sandbox Code Playgroud)
但这并没有进行任何明显的更改。
我目前正在这样设置我的navigationView
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarHidden(true)
}
Run Code Online (Sandbox Code Playgroud)
其中FileBrowserView是具有列表和像这样定义的单元格的视图
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: "")
}
}
Run Code Online (Sandbox Code Playgroud)
我确实要注意,这里的最终目标是您将能够单击这些单元格来更深地浏览到文件树,因此在更深层的导航上应该在栏上显示“后退”按钮,但是我不需要在我的初始视图中排名最高。
gra*_*ell 35
由于某些原因,SwiftUI要求您还设置.navigationBarTitle为.navigationBarHidden可以正常工作。
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarTitle("")
.navigationBarHidden(true)
}
Run Code Online (Sandbox Code Playgroud)
正如@Peacemoon在注释中指出的那样,无论您是否在后续视图中进行设置navigationBarHidden,当您在导航堆栈中进行更深入的浏览时,导航栏将保持隐藏false。就像我在评论中说的那样,这可能是由于Apple实施不佳或仅是糟糕的文档(谁知道,也许有一种“正确”的方式来实现)的结果。
无论如何,我想出了一种解决方法,似乎可以产生原始海报的预期效果。我很犹豫地推荐它,因为它看上去似乎不必要,但如果没有任何隐藏和取消隐藏导航栏的简单方法,这就是我能做的最好的事情。
本示例使用三个视图- View1具有隐藏的导航栏,View2并且View3两个视图均带有可见的带有标题的导航栏。
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")
}
}
Run Code Online (Sandbox Code Playgroud)
设置navigationBarHidden到false导航堆栈上的更深层次的看法似乎并不恰当覆盖最初设置视图的偏好navigationBarHidden来true,所以唯一的解决方法我能想出是使用绑定改变原来的观点的偏好时,一个新的视图被推到导航堆栈上。
就像我说的那样,这是一个棘手的解决方案,但是如果没有Apple的官方解决方案,这就是我能想到的最好的解决方案。
The*_*ow_ 25
a 的目的NavigationView是在视图顶部添加导航栏。在 iOS 中,有两种导航栏:大导航栏和标准导航栏。
如果你不想要导航栏:
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
Run Code Online (Sandbox Code Playgroud)
如果你想要一个大的导航栏(通常用于你的顶级视图):
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarTitle(Text("Title"))
}
Run Code Online (Sandbox Code Playgroud)
如果您想要标准(内联)导航栏(通常用于子级视图):
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarTitle(Text("Title"), displayMode: .inline)
}
Run Code Online (Sandbox Code Playgroud)
希望这个回答能帮到你。
更多信息:Apple 文档
Pet*_*inz 23
视图修饰符使它变得容易:
//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() )
}
}
Run Code Online (Sandbox Code Playgroud)
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()
}
}
}
Run Code Online (Sandbox Code Playgroud)
Min*_*er3 14
如果您将标题设置为要删除空间的视图的内联,则不需要在具有 NavigationView 的视图上完成此操作,但也需要导航。
.navigationBarTitle("", displayMode: .inline)
Run Code Online (Sandbox Code Playgroud)
init() {
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
UINavigationBar.appearance().shadowImage = UIImage()
}
Run Code Online (Sandbox Code Playgroud)
如果要在屏幕之间更改外观,请更改相应视图中的外观
Fem*_*keo 10
我还尝试了此页面上提到的所有解决方案,但只发现 @graycampbell 解决方案运行良好,动画效果良好。所以我试图创造一个我可以在整个应用程序中使用的价值,我可以通过hackingwithswift.com的例子在任何地方访问
我创建了一个ObservableObject类
class NavBarPreferences: ObservableObject {
@Published var navBarIsHidden = true
}
Run Code Online (Sandbox Code Playgroud)
并将其传递给初始视图,SceneDelegate就像这样
var navBarPreferences = NavBarPreferences()
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(navBarPreferences))
Run Code Online (Sandbox Code Playgroud)
然后ContentView我们可以像这样跟踪这个 Observable 对象并创建一个链接到SomeView:
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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在访问第二个视图(SomeView)时,我们像这样再次隐藏它:
struct SomeView: View {
@EnvironmentObject var navBarPrefs: NavBarPreferences
var body: some View {
Text("Hello second screen")
.onAppear {
self.navBarPrefs.navBarIsHidden = false
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了保持预览正常工作,将 NavBarPreferences 添加到预览中,如下所示:
struct SomeView_Previews: PreviewProvider {
static var previews: some View {
SomeView().environmentObject(NavBarPreferences())
}
}
Run Code Online (Sandbox Code Playgroud)
Osm*_*man 10
将以下代码放在您的 NextView 上
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
Run Code Online (Sandbox Code Playgroud)
但是,在通过 NavigationLink 推送到 NextView 时,您还必须添加如下修饰符:
NavigationLink(
destination: NextView()
.navigationBarTitle("")
.navigationBarHidden(true)
) {
Text("NEXT VIEW")
}
Run Code Online (Sandbox Code Playgroud)
闪电狮*_*闪电狮 10
您不需要设置标题,只需使用.stack
NavigationView {
VStack {
Color.cyan
}
.navigationBarHidden(true)
}
.navigationViewStyle(.stack) // Here
Run Code Online (Sandbox Code Playgroud)
有一个专用的修饰符可以使导航栏占用更少的空间:
.navigationBarTitleDisplayMode(.inline)
Run Code Online (Sandbox Code Playgroud)
不再需要隐藏导航栏或设置其标题。
对我来说,我将 the.navigationBarTitle应用于 theNavigationView而 not toList是罪魁祸首。这在 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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个存在于SwiftUI蝽(仍然作为Xcode的11.2.1)。我ViewModifier根据现有答案中的代码编写了一个来解决这个问题:
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())
}
}
Run Code Online (Sandbox Code Playgroud)
您可以像这样扩展本机View协议:
extension View {
func hideNavigationBar() -> some View {
self
.navigationBarTitle("", displayMode: .inline)
.navigationBarHidden(true)
}
}
Run Code Online (Sandbox Code Playgroud)
然后只需调用例如:
ZStack {
*YOUR CONTENT*
}
.hideNavigationBar()
Run Code Online (Sandbox Code Playgroud)
对我来说,这是因为我正在从现有的推送我的 NavigationView。实际上有一个在另一个里面。如果您来自 NavigationView,则无需在下一个中创建一个,因为您已经在 NavigatonView 中。
| 归档时间: |
|
| 查看次数: |
2384 次 |
| 最近记录: |