代码之家  ›  专栏  ›  技术社区  ›  Mark

为什么在运行“取消”按钮后导航项按钮会断开?

  •  0
  • Mark  · 技术社区  · 5 年前

    当您在导航栏项目中显示modal from按钮时,SwiftUI中有一个错误。 在下面的代码中,按钮1按预期工作,但按钮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模拟器和iOS 13.3.1 iPhone XS中。

    有什么办法可以让按钮正常工作吗?

    编辑:

    1. 似乎是点击区域向下的某个地方,可以点击下面的按钮来显示模态。

    临时解决方案是使用内联导航栏模式: .navigationBarTitle("Main", displayMode: .inline)

    0 回复  |  直到 5 年前
        1
  •  16
  •   Asperi    4 年前

    问题是,在工作表关闭后,导航栏按钮的布局不好(似乎受到了破坏)

    它在视图层次结构调试中清晰可见:

    demo

    这里有一个解决方案(当然是解决方案,但很安全,因为即使问题得到解决,它也会继续工作)。这样做的目的不是为了对抗坏的布局,而是创建另一个按钮,因此布局引擎本身会删除旧的坏按钮,并添加一个新的刷新布局。这方面的仪器非常有名——使用 .id()

    demo2

    所以修改代码:

    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()
                    }
            }
        }
    }
    

    backup