SwiftUI 中存在一个问题,即使用 .edgesIgnoringSafeArea(.bottom) 时,某些 View 在垂直方向上变得比设备大小更大。在高度为 812 像素的 iPhone 11 Pro 上,我看到尺寸为 846 的 View 。我正在使用调试 View 层次结构来验证它。这已经在 Xcode 11.4.1 和 11.1 上进行了测试,并且存在于两个版本中,并且可能存在于两者之间。
我在下面包含了示例代码。
我很确定这是一个 SwiftUI 错误,但想知道是否有人有解决方法。我需要 EdgeIgnoringSafeArea(.bottom) 代码来绘制 TabBar,并在隐藏自定义选项卡栏时让 ProfileView() 延伸到屏幕底部。
struct ContentView: View {
var body: some View {
MainTabView()
}
}
struct MainTabView : View {
enum Item : CaseIterable {
case home
case resources
case profile
}
@State private var selected : Item = .home
var body: some View {
VStack(spacing: 0.0) {
ZStack {
HomeView()
.zIndex(selected == .home ? 1 : 0)
ResourcesView()
.zIndex(selected == .resources ? 1 : 0)
ProfileView()
.zIndex(selected == .profile ? 1 : 0)
}
// Code here for building and showing/hiding a Toolbar
// Basically just a HStack with a few buttons in it
}
.edgesIgnoringSafeArea(.bottom) // <- This causes the screen to jump to 846
}
}
struct ProfileView : View {
@State private var showQuestionnaireView = false
var body: some View {
NavigationView {
ZStack {
NavigationLink(destination: QuestionnaireView( showQuestionnaireView:$showQuestionnaireView),
isActive: $showQuestionnaireView) {
Text("Show Questionnaire View")
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
}
struct QuestionnaireView : View {
@Binding var showQuestionnaireView : Bool
var body: some View {
GeometryReader { screenGeometry in
ZStack {
Color.orange
VStack {
Text("Top")
Spacer()
Text("Bottom")
}
}
}
}
}
HomeView() 和 ResourcesView() 只是 ProfileView() 的副本,它们做自己的事情。
当您运行它时,您将看到一个按钮,按下该按钮,一个隐藏的导航堆栈 View 将推送到 QuestionnaireView 上,该 View 包含一个带有两个文本字段的 VStack,由于此问题,您将看不到这两个文本字段。可以理解的是,顶部的一个位于凹口后面,但底部的一个位于屏幕底部。在我的实际项目中,这个问题在运行时很少出现,但在深色模式和浅色模式之间切换会显示出来。上面的代码中不需要切换外观。
编辑:FB7677794,对于任何有兴趣的人来说,自三周前提交以来尚未收到 Apple 的任何更新。
EDIT2:向 MainTabBar 添加了更多代码
更新:这已在 Xcode 12 Beta 2 中修复
最佳答案
阅读更新后的问题后,我做了一些更改并尝试制作一个小型演示。在此,我使用与之前相同的方法,将 NavigationView
放入主选项卡 View 中,这样您就不必在每次进入或离开主选项卡 View 时隐藏和显示。
import SwiftUI
struct ContentView: View {
var body: some View {
MainTabView()
}
}
struct MainTabView : View {
enum Item : CaseIterable {
case home
case resources
case profile
}
@State private var selected : Item = .home
var body: some View {
NavigationView {
VStack(spacing: 0.0) {
ZStack {
Group {
HomeView()
.zIndex(selected == .home ? 1 : 0)
ResourcesView()
.zIndex(selected == .resources ? 1 : 0)
ProfileView()
.zIndex(selected == .profile ? 1 : 0)
}
.frame(minWidth: .zero, maxWidth: .infinity, minHeight: .zero, maxHeight: .infinity)
.background(Color.white)
}
HStack {
Group {
Image(systemName: "house.fill")
.onTapGesture {
self.selected = .home
}
Spacer()
Image(systemName: "plus.app.fill")
.onTapGesture {
self.selected = .resources
}
Spacer()
Image(systemName: "questionmark.square.fill")
.onTapGesture {
self.selected = .profile
}
}
.padding(.horizontal, 30)
}
.frame(height: 40)
.foregroundColor(Color.white)
.background(Color.gray)
// Code here for building and showing/hiding a Toolbar
// Basically just a HStack with a few buttons in it
}
.edgesIgnoringSafeArea(.bottom)
} // <- This causes the screen to jump to 846
}
}
struct ProfileView : View {
@State private var showQuestionnaireView = false
var body: some View {
// NavigationView {
ZStack {
NavigationLink(destination: QuestionnaireView( showQuestionnaireView:$showQuestionnaireView),
isActive: $showQuestionnaireView) {
Text("Show Questionnaire View")
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
// }
}
}
struct QuestionnaireView : View {
@Binding var showQuestionnaireView : Bool
var body: some View {
GeometryReader { screenGeometry in
ZStack {
Color.orange
VStack {
Text("Top")
Spacer()
Text("Bottom")
}
}
.edgesIgnoringSafeArea(.bottom)
}
}
}
struct HomeView: View {
var body: some View {
NavigationLink(destination: SecondView()) {
Text("Home View")
}
}
}
struct ResourcesView: View {
var body: some View {
NavigationLink(destination: SecondView()) {
Text("Resources View")
}
}
}
struct SecondView: View {
var body: some View {
Text("Second view in navigation")
.background(Color.black)
.foregroundColor(.white)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewDevice(PreviewDevice(rawValue: "iPhone 11"))
}
}
关于layout - 使用 .edgesIgnoringSafeArea() 时,SwiftUI 布局会超出设备边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61471262/