簡體   English   中英

SwiftUI - 顯示工作表后導航欄按鈕不可點擊

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM