1

I'm using this .if extension which works great and should be added to SwiftUI, however it won't work in this case to check #available because #available may only be used as condition of an 'if', 'guard' or 'while' statement How can I make it work with this .if, anyway?

    //Does not compile for #available may only be used as condition of an 'if', 'guard' or 'while' statement
   ForEach...
   .if(#available(iOS 15.0, *)) { $0.refreshable {
                        
                    } }

extension View {
  @ViewBuilder
  func `if`<Transform: View>(
    _ condition: Bool,
    transform: (Self) -> Transform
  ) -> some View {
    if condition {
      transform(self)
    } else {
      self
    }
  }
}
GarySabo
  • 5,806
  • 5
  • 49
  • 124

1 Answers1

4

I would typically just do .if(true) and then check availability inside the closure. Unfortunately, we can't check for availability in the if modifier.

Example:

struct ContentView: View {
    var body: some View {
        List {
            Text("Hello")
            /* More list items... */
        }
        .if(true) {
            if #available(iOS 15, *) {
                $0.refreshable {
                    //
                }
            } else {
                $0
            }
        }
    }
}

Added @ViewBuilder to transform parameter so you can return different View types in the if:

extension View {
    @ViewBuilder func `if`<Transform: View>(_ condition: Bool, @ViewBuilder transform: (Self) -> Transform) -> some View {
        if condition {
            transform(self)
        } else {
            self
        }
    }
}
George
  • 25,988
  • 10
  • 79
  • 133
  • Thanks can you elaborate on how you would use this, for example to add .refreshable as I am trying to do to a list? – GarySabo Aug 16 '21 at 20:24
  • @GarySabo See the example at the top of my answer. – George Aug 16 '21 at 20:41
  • oh I see, you are using `.if(true)` as kind of a hack to be able to nest the if available check inside a view's body...very clever! – GarySabo Aug 16 '21 at 20:54