SwiftUI模态表示只能在navigationBarItems中使用一次 [英] SwiftUI modal presentation works only once from navigationBarItems

查看:178
本文介绍了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)
        }
    }
}

该错误来自去年年中,但仍存在于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天全站免登陆