(SwiftUI) 谁能告诉我为什么我的 NavigationView 在页脚中创建额外的 NavigationBars 和空白 space? (包括视频)
(SwiftUI) can anyone tell me why my NavigationView is creating extra NavigationBars and blank space in the footer? (video included)
我有一个有 3 个视图的应用程序。它们通过 NavigationView 连接,并具有 link 到下一个视图的 NavigationLinks。但是,所有视图都是使用额外的 NavigationBar 创建的,并且底部有许多空白 space,每次您单击视图并返回主页时,这些空白都会在屏幕上移动。我记得几天前我从 HomeView() 转到 TimerView() 时遇到了这个问题,但我不确定我是如何摆脱它的。而且我绝对没有摆脱它,因为我仍然遇到同样的问题。而且我也不记得我第一次是如何解决这个问题的。我看到其他帖子说我应该将 navigationBar 颜色设置为 clear 但这什么也没做。不确定发生了什么。关于这个主题的大多数其他帖子都是关于删除顶部的 space,很少有人谈论底部的空白 space,所以我不太确定该怎么做。
我进入捕获视图层次结构,我看到在创建视图时创建了白色页脚栏,但随后似乎只是堆叠在所有其他视图之上,直到应用程序无法使用。在 iPhone 12 和 iOS 15.0.
模拟器中使用 Xcode 13.1 和 运行
这是捕获视图层次结构中的视频和图片https://imgur.com/a/jBprYbN
这是代码
struct ContentView: View {
@State private var selectedTab = 0
let numTabs = 2
let minDragTranslationForSwipe: CGFloat = 50
@State var secondScreenShown = true
@State private var tabSelection = 0
@State private var tappedTwice:Bool = false
@State private var homeID = UUID()
var handler: Binding<Int> { Binding (
get: {self.tabSelection},
set: {
if [=11=] == self.tabSelection {
tappedTwice = true
print("tappedTwice = true")
}
self.tabSelection = [=11=]
}
)}
init() {
UITabBar.appearance().isTranslucent = false
}
var body: some View {
TabView(selection:handler) {
NavigationView {
HomeView()
.id(homeID)
.tabItem {
Label("Home", systemImage: "house.fill")
}.tag(0)
.onChange(of: tappedTwice, perform: { tappedTwice in
guard tappedTwice else { return }
homeID = UUID()
self.tappedTwice = false
})
}
}
.edgesIgnoringSafeArea(.all)
.frame(
minWidth: UIScreen.main.bounds.width,
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
}
}
这是 HomeView()
struct HomeView: View {
@State var secondScreenShown = false
@State var timerVal = 1
@State private var chosenSound = "None"
var times = [1, 2, 3, 4, 5, 10, 15, 20, 30, 45, 60]
var sounds = ["None", "Creepy Kids", "Conjuring The Dark Ones", "The Forbidden Forest" ]
init() {
UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
UITableView.appearance().tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
}
var body: some View {
// NavigationView {
VStack {
VStack {
VStack {
Group {
VStack {
NavigationLink(
destination: TimerView(timerScreenShown: $secondScreenShown, timerVal: timerVal, chosenSound: chosenSound, initialTime: timerVal),
isActive: $secondScreenShown,
label: {Text("Go")
.font(.title2)
.padding()
.frame(minWidth: 250)
.overlay(
Capsule(style: .continuous)
.stroke(Color.black, lineWidth: 3)
)
})
.frame(minWidth: /*@START_MENU_TOKEN@*/0/*@END_MENU_TOKEN@*/, maxWidth: 100, alignment: .bottom)
.padding(.top, 10)
} // third group
}
} // VStack just outside rectangle
.frame(
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
.padding()
// ) // rectangle.overlay()
} // VStack
.edgesIgnoringSafeArea([.top, .bottom])
.background(Color.pink)
.frame(
minWidth: UIScreen.main.bounds.width,
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
// } // NavigationView
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarTitle("main level")
}
}
}
这是 TimerView()
struct TimerView: View {
@Binding var timerScreenShown:Bool
@State var timerVal:Int
@State var chosenSound:String
@State private var showNextView = false
@State private var paused = false
var initialTime:Int
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack {
VStack {
VStack {
NavigationLink(
destination: HomeView(),
label: {Text("Home Page")})
.font(.title2)
.frame(minWidth: 0,maxWidth: 200, alignment: .center)
.overlay(
Capsule(style: .continuous)
.stroke(Color.black, lineWidth: 3)
)
.padding(.top, 35)
// } // else
} // innermost VStack
.frame(
alignment: .center
)
.padding()
// )
} // VStack 2
.frame(
minWidth: UIScreen.main.bounds.width,
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
} // VStack
.edgesIgnoringSafeArea([.top, .bottom])
.background(Color.purple
// Image("HomePageBackground")
// .resizable()
// .ignoresSafeArea()
)
.frame(
minWidth: UIScreen.main.bounds.width,
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
.onAppear(){
UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
UITableView.appearance().tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
}
.navigationBarTitle("timer view")
} // View
}
所以是的,很明显在某处创建了额外的导航视图,但我不确定在哪里。同样明显的是,页脚中的空白 space 是在加载视图时创建的,但我不知道在哪里。所以是的,我们将不胜感激。
如果有任何 brackets/parenthesis 遗漏是因为我在删除注释掉的无关代码时不小心删除了它。
问题是由 UITabBar.appearance().isTranslucent = false
行引起的——如果没有那行,正如您在评论中确认的那样,它的行为符合预期。
这是一个工作版本,其中包含关于该行的注释:
import SwiftUI
struct ContentView: View {
init() {
UITabBar.appearance().isTranslucent = false //REMOVE THIS and functionality will be as-expected
}
var body: some View {
TabView {
NavigationView {
HomeView()
}.tabItem {
Label("Home", systemImage: "house.fill")
}
.navigationViewStyle(StackNavigationViewStyle())
.tag(0)
}
}
}
struct TimerView: View {
var body: some View {
VStack {
NavigationLink(
destination: HomeView(),
label: {Text("Home Page")})
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.background(Color.purple)
.edgesIgnoringSafeArea([.top, .bottom])
.navigationBarTitle("timer view")
}
}
struct HomeView: View {
var body: some View {
VStack {
NavigationLink(
destination: TimerView(),
label: {
Text("Go")
})
.frame(minWidth: 0, maxWidth: 100, alignment: .bottom)
.padding(.top, 10)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.pink)
.edgesIgnoringSafeArea([.top, .bottom])
.navigationBarTitle("main level")
}
}
我有一个有 3 个视图的应用程序。它们通过 NavigationView 连接,并具有 link 到下一个视图的 NavigationLinks。但是,所有视图都是使用额外的 NavigationBar 创建的,并且底部有许多空白 space,每次您单击视图并返回主页时,这些空白都会在屏幕上移动。我记得几天前我从 HomeView() 转到 TimerView() 时遇到了这个问题,但我不确定我是如何摆脱它的。而且我绝对没有摆脱它,因为我仍然遇到同样的问题。而且我也不记得我第一次是如何解决这个问题的。我看到其他帖子说我应该将 navigationBar 颜色设置为 clear 但这什么也没做。不确定发生了什么。关于这个主题的大多数其他帖子都是关于删除顶部的 space,很少有人谈论底部的空白 space,所以我不太确定该怎么做。
我进入捕获视图层次结构,我看到在创建视图时创建了白色页脚栏,但随后似乎只是堆叠在所有其他视图之上,直到应用程序无法使用。在 iPhone 12 和 iOS 15.0.
模拟器中使用 Xcode 13.1 和 运行这是捕获视图层次结构中的视频和图片https://imgur.com/a/jBprYbN
这是代码
struct ContentView: View {
@State private var selectedTab = 0
let numTabs = 2
let minDragTranslationForSwipe: CGFloat = 50
@State var secondScreenShown = true
@State private var tabSelection = 0
@State private var tappedTwice:Bool = false
@State private var homeID = UUID()
var handler: Binding<Int> { Binding (
get: {self.tabSelection},
set: {
if [=11=] == self.tabSelection {
tappedTwice = true
print("tappedTwice = true")
}
self.tabSelection = [=11=]
}
)}
init() {
UITabBar.appearance().isTranslucent = false
}
var body: some View {
TabView(selection:handler) {
NavigationView {
HomeView()
.id(homeID)
.tabItem {
Label("Home", systemImage: "house.fill")
}.tag(0)
.onChange(of: tappedTwice, perform: { tappedTwice in
guard tappedTwice else { return }
homeID = UUID()
self.tappedTwice = false
})
}
}
.edgesIgnoringSafeArea(.all)
.frame(
minWidth: UIScreen.main.bounds.width,
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
}
}
这是 HomeView()
struct HomeView: View {
@State var secondScreenShown = false
@State var timerVal = 1
@State private var chosenSound = "None"
var times = [1, 2, 3, 4, 5, 10, 15, 20, 30, 45, 60]
var sounds = ["None", "Creepy Kids", "Conjuring The Dark Ones", "The Forbidden Forest" ]
init() {
UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
UITableView.appearance().tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
}
var body: some View {
// NavigationView {
VStack {
VStack {
VStack {
Group {
VStack {
NavigationLink(
destination: TimerView(timerScreenShown: $secondScreenShown, timerVal: timerVal, chosenSound: chosenSound, initialTime: timerVal),
isActive: $secondScreenShown,
label: {Text("Go")
.font(.title2)
.padding()
.frame(minWidth: 250)
.overlay(
Capsule(style: .continuous)
.stroke(Color.black, lineWidth: 3)
)
})
.frame(minWidth: /*@START_MENU_TOKEN@*/0/*@END_MENU_TOKEN@*/, maxWidth: 100, alignment: .bottom)
.padding(.top, 10)
} // third group
}
} // VStack just outside rectangle
.frame(
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
.padding()
// ) // rectangle.overlay()
} // VStack
.edgesIgnoringSafeArea([.top, .bottom])
.background(Color.pink)
.frame(
minWidth: UIScreen.main.bounds.width,
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
// } // NavigationView
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarTitle("main level")
}
}
}
这是 TimerView()
struct TimerView: View {
@Binding var timerScreenShown:Bool
@State var timerVal:Int
@State var chosenSound:String
@State private var showNextView = false
@State private var paused = false
var initialTime:Int
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack {
VStack {
VStack {
NavigationLink(
destination: HomeView(),
label: {Text("Home Page")})
.font(.title2)
.frame(minWidth: 0,maxWidth: 200, alignment: .center)
.overlay(
Capsule(style: .continuous)
.stroke(Color.black, lineWidth: 3)
)
.padding(.top, 35)
// } // else
} // innermost VStack
.frame(
alignment: .center
)
.padding()
// )
} // VStack 2
.frame(
minWidth: UIScreen.main.bounds.width,
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
} // VStack
.edgesIgnoringSafeArea([.top, .bottom])
.background(Color.purple
// Image("HomePageBackground")
// .resizable()
// .ignoresSafeArea()
)
.frame(
minWidth: UIScreen.main.bounds.width,
maxWidth: .infinity,
minHeight: UIScreen.main.bounds.height,
maxHeight: .infinity,
alignment: .center
)
.onAppear(){
UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
UITableView.appearance().tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
}
.navigationBarTitle("timer view")
} // View
}
所以是的,很明显在某处创建了额外的导航视图,但我不确定在哪里。同样明显的是,页脚中的空白 space 是在加载视图时创建的,但我不知道在哪里。所以是的,我们将不胜感激。
如果有任何 brackets/parenthesis 遗漏是因为我在删除注释掉的无关代码时不小心删除了它。
问题是由 UITabBar.appearance().isTranslucent = false
行引起的——如果没有那行,正如您在评论中确认的那样,它的行为符合预期。
这是一个工作版本,其中包含关于该行的注释:
import SwiftUI
struct ContentView: View {
init() {
UITabBar.appearance().isTranslucent = false //REMOVE THIS and functionality will be as-expected
}
var body: some View {
TabView {
NavigationView {
HomeView()
}.tabItem {
Label("Home", systemImage: "house.fill")
}
.navigationViewStyle(StackNavigationViewStyle())
.tag(0)
}
}
}
struct TimerView: View {
var body: some View {
VStack {
NavigationLink(
destination: HomeView(),
label: {Text("Home Page")})
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.background(Color.purple)
.edgesIgnoringSafeArea([.top, .bottom])
.navigationBarTitle("timer view")
}
}
struct HomeView: View {
var body: some View {
VStack {
NavigationLink(
destination: TimerView(),
label: {
Text("Go")
})
.frame(minWidth: 0, maxWidth: 100, alignment: .bottom)
.padding(.top, 10)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.pink)
.edgesIgnoringSafeArea([.top, .bottom])
.navigationBarTitle("main level")
}
}