ios - SwiftUI 模态演示仅在 navigationBarItems 中有效
问题描述
当您从导航栏项目内的按钮显示模式时,这是 SwiftUI 中的一个错误。在下面的代码中 Button 1 按预期工作,但 Button 2 只工作一次:
struct DetailView: View {
@Binding var isPresented: Bool
@Environment (\.presentationMode) var presentationMode
var body: some View {
NavigationView {
Text("OK")
.navigationBarTitle("Details")
.navigationBarItems(trailing: Button(action: {
self.isPresented = false
// or:
// self.presentationMode.wrappedValue.dismiss()
}) {
Text("Done").bold()
})
}
}
}
struct ContentView: View {
@State var showSheetView = false
var body: some View {
NavigationView {
Group {
Text("Master")
Button(action: { self.showSheetView.toggle() }) {
Text("Button 1")
}
}
.navigationBarTitle("Main")
.navigationBarItems(trailing: Button(action: {
self.showSheetView.toggle()
}) {
Text("Button 2").bold()
})
}.sheet(isPresented: $showSheetView) {
DetailView(isPresented: self.$showSheetView)
}
}
}
这个 bug 是从去年年中开始的,现在还在 Xcode 11.3.1 + iOS 13.3 Simulator 和 iOS 13.3.1 iPhone XS 中。
这里有任何解决方法可以使按钮工作吗?
编辑:
- 似乎是点击区域向下某处,并且可以点击下面的按钮以显示模式。
对此的临时解决方案是使用内联导航栏模式:
.navigationBarTitle("Main", displayMode: .inline)
解决方案
好吧,问题在于工作表关闭后导航栏按钮的布局错误(似乎约束被破坏)
在视图层次结构调试中清晰可见:
这是一个修复(当然是解决方法,但安全,因为即使问题得到修复,它也会继续工作)。这个想法不是与损坏的布局作斗争,而只是创建另一个按钮,因此布局引擎本身会删除旧的坏按钮并添加新的令人耳目一新的布局。用于此的工具是众所周知的 - 使用.id()
于是修改了代码:
struct ContentView: View {
@State var showSheetView = false
@State private var navigationButtonID = UUID()
var body: some View {
NavigationView {
Group {
Text("Master")
Button(action: { self.showSheetView.toggle() }) {
Text("Button 1")
}
}
.navigationBarTitle("Main")
.navigationBarItems(trailing: Button(action: {
self.showSheetView.toggle()
}) {
Text("Button 2").bold() // recommend .padding(.vertical) here
}
.id(self.navigationButtonID)) // force new instance creation
}
.sheet(isPresented: $showSheetView) {
DetailView(isPresented: self.$showSheetView)
.onDisappear {
// update button id after sheet got closed
self.navigationButtonID = UUID()
}
}
}
}
推荐阅读
- optimization - 向量化索引识别以加快 GPU 处理速度
- javascript - 单击按钮时,使用 reactjs 更改单击按钮的类名以及该组中的其他按钮
- asp.net - ASP.NET Core 将 int 值从 ajax 传递给 View
- typescript - 打字稿:要求枚举中的所有键都是有效类型
- neo4j - neo4j 发现所有连接非常慢
- xamarin.forms - 如何知道 Xamarin ListView 是否聚焦
- typescript - 单击 SVG 图标以标记复选框 - Protractor - TypeScript
- php - 带有敏感数据的订单状态链接(无身份验证/登录)
- javascript - 使用 jquery 的 requirejs 错误
- reactjs - CustomHook:避免在回调中使用旧的 Scope