gpt4 book ai didi

ios - 仅在显示为模式时才显示前导 navigationBarItems 按钮

转载 作者:行者123 更新时间:2023-12-01 19:34:58 24 4
gpt4 key购买 nike

我有一个可以显示为模式的 View ,也可以简单地推送到导航堆栈上。当它被按下时,它在左上角有后退按钮,当它显示为模态时,我想添加一个关闭按钮(我的许多测试人员不容易弄清楚他们可以滑下模态并且真的需要一个明确的关闭按钮)。

现在,我有多个问题。

  • 如何确定 View 是否以模态方式显示?或者,如果它不是导航堆栈上的第一个 View ?在 UIKit 中有多种方法可以轻松做到这一点。添加 presentationMode @Environment变量没有帮助,因为它的 isPresented value 也适用于推送的屏幕。我当然可以通过 isModal改变自己,但似乎很奇怪这是唯一的方法?
  • 如何有条件地添加领先的 navigationBarItem?问题是如果你给 nil ,甚至默认的后退按钮也被隐藏。

  • 将代码复制并粘贴到 Xcode 中并使用:

    import SwiftUI

    struct ContentView: View {
    @State private var showModal = false

    var body: some View {
    NavigationView {
    VStack(spacing: 20) {
    Button("Open modally") {
    self.showModal = true
    }

    NavigationLink("Push", destination: DetailView(isModal: false))
    }
    .navigationBarTitle("Home")
    }
    .sheet(isPresented: $showModal) {
    NavigationView {
    DetailView(isModal: true)
    }
    }
    }
    }

    struct DetailView: View {
    @Environment(\.presentationMode) private var presentationMode
    let isModal: Bool

    var body: some View {
    Text("Hello World")
    .navigationBarTitle(Text("Detail"), displayMode: .inline)
    .navigationBarItems(leading: closeButton, trailing: deleteButton)
    }

    private var closeButton: some View {
    Button(action: { self.presentationMode.wrappedValue.dismiss() }) {
    Image(systemName: "xmark")
    .frame(height: 36)
    }
    }

    private var deleteButton: some View {
    Button(action: { print("DELETE") }) {
    Image(systemName: "trash")
    .frame(height: 36)
    }
    }
    }

    struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
    ContentView()
    }
    }

    如果我改变 closeButton返回可选的 AnyView?然后返回 nilisModal是假的,我根本没有后退按钮。我也打不通 navigationBarItems两次,一次是前导按钮,一次是尾随按钮,因为后一个调用会覆盖第一个调用。我有点卡在这里。

    最佳答案

    好的,我做到了。它不漂亮,我非常愿意接受不同的建议,但它有效😅

    import SwiftUI

    extension View {
    func eraseToAnyView() -> AnyView {
    AnyView(self)
    }

    public func conditionalNavigationBarItems(_ condition: Bool, leading: AnyView, trailing: AnyView) -> some View {
    Group {
    if condition {
    self.navigationBarItems(leading: leading, trailing: trailing)
    } else {
    self
    }
    }
    }
    }

    struct ContentView: View {
    @State private var showModal = false

    var body: some View {
    NavigationView {
    VStack(spacing: 20) {
    Button("Open modally") {
    self.showModal = true
    }

    NavigationLink("Push", destination: DetailView(isModal: false))
    }
    .navigationBarTitle("Home")
    }
    .sheet(isPresented: $showModal) {
    NavigationView {
    DetailView(isModal: true)
    }
    }
    }
    }

    struct DetailView: View {
    @Environment(\.presentationMode) private var presentationMode
    let isModal: Bool

    var body: some View {
    Text("Hello World")
    .navigationBarTitle(Text("Detail"), displayMode: .inline)
    .navigationBarItems(trailing: deleteButton)
    .conditionalNavigationBarItems(isModal, leading: closeButton, trailing: deleteButton)
    }

    private var closeButton: AnyView {
    Button(action: { self.presentationMode.wrappedValue.dismiss() }) {
    Image(systemName: "xmark")
    .frame(height: 36)
    }.eraseToAnyView()
    }

    private var deleteButton: AnyView {
    Button(action: { print("DELETE") }) {
    Image(systemName: "trash")
    .frame(height: 36)
    }.eraseToAnyView()
    }
    }

    struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
    ContentView()
    }
    }

    关于ios - 仅在显示为模式时才显示前导 navigationBarItems 按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60565902/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com