5

I'm working on an app that supports iOS 14 and up, but I would like to use some of the SwiftUI 3 property wrappers like @FocusState.

How can I work around the Stored properties cannot be marked potentially unavailable error?

Here is the simplified version of our code, it works with Xcode 13, but fails to compile with Xcode 14.

struct MyView: View {
  enum Field: Hashable {
    case username
  }

  @State private var myText: String = ""

  @available(iOS 15, *)
  @FocusState private var focusedField: Field?

  var body: some View {
    if #available(iOS 15, *) {
      TextEditor(text: $myText)
        .focused($focusedField, equals: .username)
    } else {
      TextEditor(text: $myText)
    }
  }
}

I cannot use a computed property with a backing storage workaround as a computed property cannot have a property wrapper.

Are there any other workarounds that I can use except for an almost identical copy of MyView?

Allan Spreys
  • 5,287
  • 5
  • 39
  • 44
  • You either need to implement `MyView` twice - Once for iOS14+ and once for earlier versions, drop the use of `@FocusState` or drop iOS13 support. Personally, that is what I would do. A device that is stuck on ios13 is 8+ years old. – Paulw11 Jul 11 '22 at 01:59
  • Hm, thanks @Paulw11, `@FocusState` is only iOS 15+ and we have about 10% of our customer base still on iOS 14, so not ready to drop support for that. I'm leaning towards writing `MyView` twice at this stage, but maybe somebody could think of a nicer workaround. – Allan Spreys Jul 11 '22 at 02:02

1 Answers1

4

A possible approach is to separate all dependent parts into one subview, and mark it as available for new OS.

Here is a demo:

struct MyView: View {
    enum Field: Hashable {
        case username
    }

    @State private var myText: String = ""

    @available(iOS 15, *)            // << here !!
    struct NewTextEditor: View {
        @Binding var text: String
        @FocusState private var focusedField: Field?

        var body: some View {
            TextEditor(text: $text)
                .focused($focusedField, equals: .username)
        }
    }


    var body: some View {
        if #available(iOS 15, *) {
            NewTextEditor(text: $myText)
        } else {
            TextEditor(text: $myText)
        }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690