The number
提供的变体中的状态会刷新整个视图,这是问题的结果,对于 UI 来说并不是最佳选择。
导航栏的解决方案(一般来说良好的风格)是将刷新部分分离到独立视图中,因此 SwiftUI 渲染引擎仅重建它。
使用 Xcode 12b3 / iOS 14 进行测试
struct TestOftenUpdate: View {
@State private var showModal = false
var body: some View {
NavigationView {
VStack {
QuickTimerView()
Button(action: { showModal.toggle() }, label: {
Text("Open Modal")
})
}
.navigationBarTitle("Home", displayMode: .inline)
.navigationBarItems(leading:
Button(action: {
showModal.toggle()
}, label: {
Text("Open Modal")
}))
.toolbar {
ToolbarItem(placement: .bottomBar) {
Button(action: {
showModal.toggle()
}, label: {
Text("Open Modal")
})
}
}
}
.sheet(isPresented: $showModal, content: {
Text("Hello, World!")
})
}
}
struct QuickTimerView: View {
@State private var number = 0
var body: some View {
VStack {
Text("Count \(number)")
Button(action: startTimer, label: {
Text("Start Timer")
})
}
}
func startTimer() {
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { (_) in
number += 1
}
}
}
With toolbar
是不同的问题 - 即使没有计时器视图,在打开第一张纸后它也不起作用,这就是为什么
因为可以看到按钮布局已损坏并且位于工具栏区域之外,这就是点击测试失败的原因 - 这是应该报告的 Apple 缺陷。
解决方法1:
将工具栏放置在导航视图之外(视觉上工具栏较小,但有时可能是合适的,因为按钮可以工作)
NavigationView {
// ... other code
}
.toolbar {
ToolbarItem(placement: .bottomBar) {
Button(action: {
showModal.toggle()
}, label: {
Text("Open Modal")
})
}
}