SwiftUI 模式演示只能从 navigationBarItems 工作一次 [英] SwiftUI modal presentation works only once from navigationBarItems

查看:19
本文介绍了SwiftUI 模式演示只能从 navigationBarItems 工作一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当您从导航栏项目内的按钮显示模态时,这是 SwiftUI 中的一个错误.在下面的代码中,按钮 1 按预期工作,但按钮 2 仅工作一次:

Here is a bug in SwiftUI when you show modal from button inside navigation bar items. In code below Button 1 works as expected, but Button 2 works only once:

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中.

This bug is from the middle of the last year, and it still in Xcode 11.3.1 + iOS 13.3 Simulator and iOS 13.3.1 iPhone XS.

这里有任何使按钮工作的解决方法吗?

Is here any workaround to make button work?

  1. 似乎点按区域向下某处,可以点按下面的按钮以显示模态.

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

Temporary solution to this is to use inline navigation bar mode: .navigationBarTitle("Main", displayMode: .inline)

推荐答案

好吧,问题出在工作表关闭后导航栏按钮的布局错误(似乎已破坏约束)

Well, the issue is in bad layout (seems broken constrains) of navigation bar button after sheet has closed

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

It is clearly visible in view hierarchy debug:

这是一个修复程序(当然是解决方法,但安全,因为即使问题得到修复,它仍将继续工作).这个想法不是与损坏的布局作斗争,而只是创建另一个按钮,因此布局引擎本身删除旧的坏按钮并添加新的刷新布局.这个工具是众所周知的 - 使用 .id()

Here is a fix (workaround of course, but safe, because even after issue be fixed it will continue working). The idea is not to fight with broken layout but just create another button, so layout engine itself remove old-bad button and add new one refreshing layout. The instrument for this is pretty known - use .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()
                }
        }
    }
}

这篇关于SwiftUI 模式演示只能从 navigationBarItems 工作一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆