[英]SwiftUI: Tap target for Navigation Bar Button misaligned after dismissing a sheet
[英]SwiftUI - Navigation bar button not clickable after sheet has been presented
几周前我刚刚开始使用 SwiftUI,我正在学习。 今天我遇到了一个问题。
当我展示一个带有 navigationBarItems 按钮的工作表,然后关闭 ModalView 并返回到 ContentView 时,我发现自己无法再次单击 navigationBarItems 按钮。
我的代码如下:
struct ContentView: View {
@State var showSheet = false
var body: some View {
NavigationView {
VStack {
Text("Test")
}.sheet(isPresented: self.$showSheet) {
ModalView()
}.navigationBarItems(trailing:
Button(action: {
self.showSheet = true
}) {
Text("SecondView")
}
)
}
}
}
struct ModalView: View {
@Environment(\.presentationMode) var presentation
var body: some View {
VStack {
Button(action: {
self.presentation.wrappedValue.dismiss()
}) {
Text("Dismiss")
}
}
}
}
我认为发生这种情况是因为presentationMode
不是从演示者视图继承的,所以演示者不知道模式已经关闭。 您可以通过将presentationMode
添加到presenter(在本例中为ContentView)来解决此问题。
struct ContentView: View {
@Environment(\.presentationMode) var presentation
@State var showSheet = false
var body: some View {
NavigationView {
VStack {
Text("Test")
}.sheet(isPresented: self.$showSheet) {
ModalView()
}.navigationBarItems(trailing:
Button(action: {
self.showSheet = true
}) {
Text("SecondView")
}
)
}
}
}
在 Xcode 12.5 上测试。
这是完整的工作示例。
这似乎是 SwiftUI 中的一个错误。 我还在 Xcode 11.5 / iOS 13.5.1 中看到这个问题。 navigationBarMode 没有任何区别。
我向 Apple 提出了问题:
FB7641003 - 点击显示工作表的 navigationBarItem 按钮有时无法识别
您可以使用随附的示例项目SwiftUISheet
(也可通过https://github.com/ralfebert/SwiftUISheet获得)来重现该问题。 它只是显示导航栏按钮的工作表。 运行应用程序并反复点击导航栏中的“加号”按钮。 当工作表弹出时,向下滑动将其关闭。 只会处理对按钮的一些点击,通常会忽略点击。
使用 iOS 13.4 (17E255) 在 Xcode 11.4 (11E146) 上进行测试。
我仍然看到 Xcode 13 RC 和 iOS 15 的这个问题。不幸的是,上面的解决方案对我不起作用。 我最终做的是向工具栏添加一个小的文本视图,其内容根据.showingSheet
属性的值而变化。
struct ContentView: View {
@State private var showingSheet = false
var body: some View {
NavigationView {
VStack {
Text("Content view")
Text("Swift UI")
}
.sheet(isPresented: $showingSheet) {
Text("This is a sheet")
}
.navigationTitle("Example")
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
// Text view workaround for SwiftUI bug
// Keep toolbar items tappable after dismissing sheet
Text(showingSheet ? " " : "").hidden()
Button(action: {
self.showingSheet = true
}) {
Label("Show Sheet", systemImage: "plus.square")
}
}
}
}
}
}
我意识到这并不理想,但这是对我有用的第一件事。 我的猜测是,根据.showingSheet
属性更改文本视图的内容会强制 SwiftUI 完全刷新工具栏组。
这是一个与.large
navigationBarItem 相关的Bug 。 您现在可以将其设置为.inline
到 go 周围:
NavigationView {
,,,
.navigationBarTitle(Text(""), displayMode: .inline)
}
要查看错误:向下拖动按钮以使其在.large
模式下工作;)
到目前为止,我仍然可以在关闭其呈现的表格后立即观察到导航按钮的混乱。
仅供参考,我正在使用 UINavigationController 包装器作为解决方法。 它运作良好。
不幸的是,我确信这种错误越多,ios 开发人员广泛使用 SwiftUI 的时间就越远。 因为这些太基础了,不容忽视。
非常hacky,但这对我有用:
Button(action: {
self.showSheet = true
}) {
Text("SecondView")
.frame(height: 96, alignment: .trailing)
}
非常hacky,但这对我有用:
我有同样的问题。 这个解决方案对我有用。
struct ContentView: View {
@State var showSheet = false
var body: some View {
NavigationView {
VStack {
Text("Test")
}.sheet(isPresented: self.$showSheet) {
ModalView()
}.navigationBarItems(trailing:
Button(action: {
self.showSheet = true
}) {
Text("SecondView")
// this is a workaround
.frame(height: 96, alignment: .trailing)
}
)
}
}
}
只有@adamwjohnson5 的回答对我有用。 我不喜欢这样做,但它是唯一适用于 Xcode 13.1 和 iOS 15.0 的解决方案。 对于有兴趣查看 iOS 15.0 目标代码的任何人,这是我的代码:
var body: some View {
NavigationView {
mainContentView
.navigationTitle(viewModel.navigationTitle)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
PlusButton {
viewModel.showAddDialog.toggle()
}
.frame(height: 96, alignment: .trailing) // Workaroud, credit: https://stackoverflow.com/a/62209223/5421557
.confirmationDialog("CatalogView.Add.DialogTitle", isPresented: $viewModel.showAddDialog, titleVisibility: .visible) {
Button("Program") {
viewModel.navigateToAddProgramView.toggle()
}
Button("Exercise") {
viewModel.navigateToAddExerciseView.toggle()
}
}
}
}
.sheet(isPresented: $viewModel.navigateToAddProgramView, onDismiss: nil) {
Text("Add Program View")
}
.sheet(isPresented: $viewModel.navigateToAddExerciseView, onDismiss: nil) {
AddEditExerciseView(viewModel: AddEditExerciseViewModel())
}
}
.navigationViewStyle(.stack)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.