Dynamically hiding view in SwiftUI

前端 未结 7 1272
-上瘾入骨i
-上瘾入骨i 2020-12-24 10:41

I\'m trying to conditionally hide a DatePicker in SwiftUI. However, I\'m having any issue with mismatched types:

var datePicker = DatePicker($da         


        
相关标签:
7条回答
  • 2020-12-24 11:11

    Rather than dynamically setting a variable and using it in my view, I found that I was able to hide or show the date picker this way:

    struct ContentView : View {
        @State var showDatePicker = true
        @State var datePickerDate: Date = Date()
    
        var body: some View {
            VStack {
                if self.showDatePicker {
                    DatePicker($datePickerDate)
                } else {
                    DatePicker($datePickerDate).hidden()
                }
            }
        }
    }
    

    Or, optionally, not including the date picker instead of hiding it:

    struct ContentView : View {
        @State var showDatePicker = true
        @State var datePickerDate: Date = Date()
    
        var body: some View {
            VStack {
                if self.showDatePicker {
                    DatePicker($datePickerDate)
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-24 11:15

    The Simplest Way:

    You can set the alpha instead, this will preserve the layout space of the view too and does not force you to add dummy views like the other answers:

    struct ContentView : View {
        @State var showDatePicker = true
        @State var datePickerDate: Date = Date()
    
        var body: some View {
            VStack {
                DatePicker($datePickerDate)
                .opacity(showDatePicker ? 1 : 0)
            }
        }
    }
    

    I hope hidden modifier gets argument later.


    A Cleaner Way (pass as an argument):

    Also, you can implement a custom function to get the visibility state as an argument:

    extension View {
        @ViewBuilder func hidden(_ shouldHide: Bool) -> some View {
            switch shouldHide {
            case true: self.hidden()
            case false: self
            }
        }
    }
    

    Now just pas the bool to the modifier:

    DatePicker($datePickerDate)
        .hidden(showDatePicker)
    

    Note that unlike the original behavior of the hidden modifier, both of these methods preserve the frame of the hiding view.

    0 讨论(0)
  • 2020-12-24 11:18

    You also have the opacity modifier on any View:

    ActivityIndicator(tint: .black)
       .opacity(self.isLoading ? 1.0 : 0.0)
    
    0 讨论(0)
  • 2020-12-24 11:27

    I created an extension, so you can use a modifier, like so to hide the view:

    Text("Hello World!")
        .isHidden(true)
    

    Or for complete removal:

    Text("Label")
        .isHidden(true, remove: true)
    

    The source code is available on GitHub here: George-J-E/HidingViews.


    Here is the code to create the View modifier:

    I recommend you use this code in its own file (remember to import SwiftUI):

    extension View {
        
        /// Hide or show the view based on a boolean value.
        ///
        /// Example for visibility:
        /// ```
        /// Text("Label")
        ///     .isHidden(true)
        /// ```
        ///
        /// Example for complete removal:
        /// ```
        /// Text("Label")
        ///     .isHidden(true, remove: true)
        /// ```
        ///
        /// - Parameters:
        ///   - hidden: Set to `false` to show the view. Set to `true` to hide the view.
        ///   - remove: Boolean value indicating whether or not to remove the view.
        @ViewBuilder func isHidden(_ hidden: Bool, remove: Bool = false) -> some View {
            if hidden {
                if !remove {
                    self.hidden()
                }
            } else {
                self
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-24 11:31

    Here is the simple way to Show/Hide view in SwiftUI.

    1. Add @State variable:

      @State var showLogo = false
      
    2. Add condition like below:

      VStack {
                  if showLogo == true {
                  Image(systemName: "house.fill")
                      .resizable()
                      .frame(width: 100, height: 100, alignment: .center)
                      .foregroundColor(Color("LightGreyFont"))
                      .padding(.bottom, 20)
                  }
                  Text("Real State App")
                      .font(Font.custom("Montserrat-Regular", size: 30))
              }.padding(.vertical, 25)
      
    3. Change state of your @State variable to Show/Hide the view like below:

      Button(action: {
                      withAnimation{
                          self.showLogo.toggle()
                      }
      
                  }, label: {
                      Text("Login").font(.system(size: 20, weight: .medium, design: .default))
                          .frame(minWidth: 0, maxWidth: .infinity, maxHeight: 50)
                          .foregroundColor(Color("BlackFont"))
                          .cornerRadius(10)
      
                  })
      

    0 讨论(0)
  • 2020-12-24 11:33

    Command-click the view in question and select the Make Conditional option in Beta 5. I did this on one of my views (LiftsCollectionView), and it generated the following:

        if suggestedLayout.size.height > 150 {
          LiftsCollectionView()
        } else {
          EmptyView()
        }
    
    0 讨论(0)
提交回复
热议问题