簡體   English   中英

SwiftUI - 如何關閉假模態視圖 - 從里面的第二個視圖,帶有關閉按鈕?

[英]SwiftUI - How to close a fake Modal View - from the second view inside it, with a close button?

我有一個棘手的設計。 我試圖有一個關閉按鈕,從任何視圖中,在“假”模態視圖中(假因為它是全屏的,多虧了我在網上找到的代碼),它將關閉模態視圖。 現在關閉按鈕在模態視圖中打開的第一個視圖中工作,但我需要它在模態視圖的下一個視圖中也能工作,因為我在這個模態視圖中有一個流程來創建一個項目。

這是我啟動 ColorNewItemView 的視圖,我的假模態視圖。

struct RecapItemToAdd: View {

  @State var isPresented: Bool = false

    var body: some View {
      NavigationView {
        
        VStack {
            
            Button(action: { withAnimation { self.isPresented.toggle()}}) {
            Image(systemName: "pencil")
                .resizable()
                .renderingMode(.original)
                .frame(width: 13, height: 17)
                .foregroundColor(UIManager.hLightGrey)
            }

        }
        
        ZStack {
             VStack(alignment: .leading) {
                 ColorNewItemView(isPresenteded: self.$isPresented)

                 Spacer()
               }


         }
         .background(Color.white)
         .edgesIgnoringSafeArea(.all)
         .offset(x: 0, y: self.isPresented ? 0 : UIApplication.shared.keyWindow?.frame.height ?? 0)
    }

   }
 
}

注意:我知道“keyWindow”已被棄用,但我不知道如何更改它。

使用 ColorNewItemView 啟動我的全屏模式視圖。 在此視圖中,關閉按鈕有效。

   struct ColorNewItemView: View {

   @State var selection: Int? = nil

   @Binding var isPresenteded: Bool

      var body: some View {
      NavigationStackView {
         VStack(alignment: .center) {

          Button(action: {
                  self.isPresenteded = false
              }) {
                  Image(systemName: "xmark.circle.fill")
                  .resizable()
                  .frame(width: 30, height: 30)
                  .foregroundColor(UIManager.hBlueLight)
              }
    
    Text("First View")
            .font(UIManager.einaTitle)
            .foregroundColor(UIManager.hDarkBlue)
    
    
    Image("black-hoodie")
    .resizable()
    .renderingMode(.original)
    .frame(width: 245, height: 300)
    
    PushView(destination: Color2NewItemView(isPresenteded: self.$isPresenteded), tag: 1, selection: $selection) {
                  
                 Button(action: {self.selection = 1}) {
                 Text("Avanti")
                      .font(UIManager.einaButton)
                      .foregroundColor(.white)
                      .frame(width: 291, height: 43)

                      .background(UIManager.buttonGradient)
                      .cornerRadius(6)
                      .shadow(color: UIManager.hBlueShadow, radius: 7, x: 0.0, y: 6.0)
                 }
              }

        }
    }
  }
 }

現在我在模態視圖中有下一個視圖,關閉按鈕開始停止工作。

    struct Color2NewItemView: View {

    @Binding var isPresenteded: Bool
    @State var selection: Int? = nil

    var body: some View {
      VStack(alignment: .center) {


                 Button(action: {
                       self.isPresenteded = false
                   }) {
                       Image(systemName: "xmark.circle.fill")
                       .resizable()
                       .frame(width: 30, height: 30)
                       .foregroundColor(UIManager.hBlueLight)
                   }

        Text("Second View")
                .font(UIManager.einaTitle)
                .foregroundColor(UIManager.hDarkBlue)


        Image("black-hoodie")
            .resizable()
            .renderingMode(.original)
            .frame(width: 245, height: 300)


        PushView(destination: FabricNewItemView(isPresenteded: $isPresenteded), tag: 1, selection: $selection) {

                         Button(action: {self.selection = 1}) {
                         Text("Tessuto")
                              .font(UIManager.einaButton)
                              .foregroundColor(.white)
                              .frame(width: 291, height: 43)

                              .background(UIManager.buttonGradient)
                              .cornerRadius(6)
                              .shadow(color: UIManager.hBlueShadow, radius: 7, x: 0.0, y: 6.0)
                         }
        }

                        Spacer()
                        .frame(height: 18)


                    PopView{
                        Text("Back")
                        .font(UIManager.einaBodySemibold)
                        .foregroundColor(UIManager.hGrey)
                    }

        }
    }
}

附言。 我還必須使用一個名為 NavigationStack 的庫,因為我在頁面底部有一個自定義后退按鈕,並且導航視圖不允許我在不使用導航欄中的后退的情況下彈出。

綁定可能會在深層視圖層次結構中丟失,因此在接收到的級別上使用它更合適。

這是使用EnvironmentKey的可能方法(與presentationMode的想法相同)

引入一些關閉的輔助環境鍵

struct DismissModalKey: EnvironmentKey {

    typealias Value = () -> ()
    static let defaultValue = { }
}

extension EnvironmentValues {
    var dismissModal: DismissModalKey.Value {
        get {
            return self[DismissModalKey.self]
        }
        set {
            self[DismissModalKey.self] = newValue
        }
    }
}

因此,在您的頂部模式視圖中,您可以注入層次結構回調以解除

struct ColorNewItemView: View {

   @State var selection: Int? = nil
   @Binding var isPresented: Bool

   var body: some View {
      NavigationStackView {
          // ... other code
      }
      .environment(\.dismissModal, { self.isPresented = false} )   // << here !!
   }
}

因此此環境值現在可用於所有子視圖,您可以將其用作

struct Color2NewItemView: View {
   @Environment(\.dismissModal) var dismissModal
   
   @State var selection: Int? = nil

   var body: some View {
      VStack(alignment: .center) {
          Button(action: {
              self.dismissModal()       // << here !!
          }) {
      
      // ... other code
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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