Xcode:版本 11.3 (11C29)
目标:运行 iOS 13.3 的模拟器
在使用工作表和 SwiftUI 时,我遇到了难以诊断的不一致行为。当我:
*NavigationView
本身使用一个按钮时,我可以始终如一地调用工作表并关闭它
* 使用NavigationView
(即navigationBarItems
)栏中的按钮,行为不一致:有时它切换没有问题,有时它会“锁定up”并且在再次运行之前大约 10 秒没有响应。在界面中四处滑动并执行其他操作似乎有助于“重置”功能。
最小可重现示例:
import SwiftUI
struct ContentView: View {
@State var isModalShowing = false
var body: some View {
NavigationView {
VStack {
List {
ForEach(1..<5) { number in
Text(String(number))
}
}
Button("First Modal Button") {
self.isModalShowing = true
}
}
.navigationBarItems(leading:
Button("Second Modal Button") {
self.isModalShowing = true
})
}
.sheet(isPresented: $isModalShowing) {
TestView(isPresented: self.$isModalShowing)
}
}
}
struct TestView: View {
@Binding var isPresented: Bool
var body: some View {
VStack {
Text("Hello SwiftUI!")
Button("Dismiss") {
self.isPresented = false
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Run Code Online (Sandbox Code Playgroud)
注意:
*First modal button
持续
按下 *Second modal button
第一次关闭模态后按下工作不一致(尝试连续使用此按钮约 5-10 次,它应该会锁定,但很难预测何时会锁定)
已经有一些关于这个的StackOverflow 问题/答案,但到目前为止没有一个对我有用,他们似乎在谈论 Xcode Betas,而我处于稳定状态(希望 11.3 是稳定的)。传递状态(@Binding
vs @Environment
)的不同方式没有帮助。在.sheet
被调用的地方移动也没有改变任何东西。我认为这也与List
和/或有关,ForEach
但我是 Swift 的新手,不确定如何进一步调试。
我相信这是一个错误。虽然我的回答不会解决这个问题,但可以给你选择考虑。
出于好奇,我对视图层次结构进行了一些调试。使用当前设置,最初导航栏按钮停留在此处(突出显示为蓝色):
然后您出示表格并相应地取消表格。解散后,导航栏按钮的位置不太对。看:
该Text
按钮停留在正确的位置,但栏按钮是从那里应该是流离失所。
但是,如果您使用NavigationLink
而不是.sheet
演示文稿,则不会发生这种位移。
嗯,这个问题普遍存在于导航栏标题的large
选项中TitleDisplayMode
,并且它是相当长一段时间的默认设置。但如果使用该inline
选项,则问题不存在。请参阅,使用该inline
选项,在工作表关闭之前和之后,导航栏按钮保持在同一位置:
这意味着,您现在有两个选择要考虑:
使用NavigationLink
而不是工作表演示。您可以通过将以下代码放在最外层View
(在您的情况下是VStack
)来完成此操作:
NavigationLink(destination: TestView(), isActive: self.$isModalShowing) {
EmptyView()
// no need to provide any other view as it will be triggered by the action
// of navigation bar button item which already provides its own view
}
Run Code Online (Sandbox Code Playgroud)注意:此
NavigationLink
选项未在Xcode 11.3或更高版本上进行测试,因为导航链接在此版本中似乎行为不当。但按预期工作到Xcode 11.2.1。有关SwiftUI 无法使用 navigationLink 来回导航的更多信息
使用inline
导航栏的选项TitleDisplayMode
作为:
.navigationBarTitle(Text("Home"), displayMode: .inline)
// you can get rid of the title "Home" with empty "" string though
Run Code Online (Sandbox Code Playgroud)