Search code examples
iosswiftswiftuiviewbuilderswiftui-view

How to wrap #available in this custom .if extension on a SwiftUI View?


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
    }
  }
}

Solution

  • You can add an extension to View that is a @ViewBuilder modifier that accepts conditionals.

    extension View {
        @ViewBuilder
        func modify(@ViewBuilder _ transform: (Self) -> (some View)?) -> some View {
            if let view = transform(self) {
                view
            } else {
                self
            }
        }
    }
    

    Example:

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