layout - 使用 .edgesIgnoringSafeArea() 时,SwiftUI 布局超出设备范围
问题描述
在 SwiftUI 中出现问题,使用 .edgesIgnoringSafeArea(.bottom) 时,某些视图在垂直方向上的增长大于设备的大小。在 812 像素高的 iPhone 11 Pro 上,我看到大小为 846 的视图。我正在使用 Debug View Hierarchy 来验证它。这已经在 Xcode 11.4.1 和 11.1 上进行了测试,并且存在于两个版本中,并且可能介于两者之间。
我在下面包含了示例代码。
我很确定这是一个 SwiftUI 错误,但想知道是否有人有解决方法。我需要edgesIgnoringSafeArea(.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() 的副本,它们做自己的事情。
当您运行它时,您将看到一个按钮,按下该按钮并在 QuestionnaireView 上推送一个隐藏的导航堆栈视图,此视图包含一个带有两个文本字段的 VStack,由于此问题,您将无法看到这两个文本字段。可以理解的是,顶部位于缺口后面,但底部位于屏幕底部。在我的真实项目中,这个问题在运行时很少出现,但是在暗模式和亮模式之间切换会显示出来。在上面的代码中,不需要切换外观。
编辑:FB7677794 对于任何感兴趣的人,自 3 周前提交以来,尚未收到 Apple 的任何更新。
EDIT2:向 MainTabBar 添加了更多代码
更新:这已在 Xcode 12 Beta 2 中修复
解决方案
这是由于NavigationView
. 当您添加自定义选项卡栏组件时,如下例所示,它限制了底部区域,NavigationView 将正确布局。
使用 Xcode 11.4 / iOS 13.4 测试
struct MainTabView : View {
var body: some View {
VStack(spacing: 0.0) {
ZStack {
Color(.cyan)
ProfileView() // << this injects NavigationView
}
HStack { // custom tab bar
Button(action: {}) { Image(systemName: "1.circle").padding() }
Button(action: {}) { Image(systemName: "2.circle").padding() }
Button(action: {}) { Image(systemName: "3.circle").padding() }
}.padding(.bottom)
}
.edgesIgnoringSafeArea(.bottom) // works !!
}
}
推荐阅读
- php - SMTP 错误 503 - 所有 RCPT 命令都被拒绝
- angular - ng-select typeahead=true multiple=true 药丸删除脚本端不起作用
- docker - 在生产环境中将 Jenkins 服务器作为 Docker 容器运行
- python - 从多标签类修改数组
- python - 您可以遍历单词列表并使用字典来跟踪每个单词的频率(计数)吗?
- dolphindb - 如何读取 .cfg 文件中的内容并将其解析成字典?
- gatsby - 拦截 Gatsby v3 页面的响应和返回状态码
- c++ - OpenMP 行为:使用 ICC 和 GCC 会产生显着不同的运行时间
- elasticsearch - Elasticsearch - 防止日期直方图地板
- mysql - 如何生成具有动态列的视图(需要通过引用表的行来创建列)