iOS voiceover for multiline input field

Hello ! I encountered the following issue with voiceover behavior on iOS15.2, also reproduced on iOS14.1:

Please note: the voiceover should be ON to reproduce the issue.

I've created the multiline input field based on UIKit object (UITextView), because I'am not able to use native SwiftUI TextEditor due to lack of 'isEditing' state. Then I placed this multiline input field into dynamic UI. All works fine If I have some dynamic controls that appears below my input field. But the input field becomes inaccessible when I have a dynamic control above my input field. I've tried to simplify my code as much as possible (please see attachment)

The input field becomes inaccessible after I tap on "Validate" button. All works fine if we move dynamic control ('validationErrorMessage') below the input field ('InputViewRepresentable').

What could you suggest in this case ?

You can do the something natively in swiftUI without using UIKit. See here:https://developer.apple.com/documentation/swiftui/textfield/focused(_:equals:)

struct LoginForm {
    enum Field: Hashable {
        case usernameField
        case passwordField
    }

    @State private var username = ""
    @State private var password = ""
    @FocusState private var focusedField: Field?

    var body: some View {
        Form {
            TextField("Username", text: $username)
                .focused($focusedField, equals: .usernameField)

            SecureField("Password", text: $password)
                .focused($focusedField, equals: .passwordField)

            EmptyView()
                  .emptyState(focusedField == .username) {
                           Text("Please enter a user name.")
                                .foregroundColor(.red)
                                .font(.footnote)
                        }

            Button("Sign In") {
                if username.isEmpty {
                    focusedField = .usernameField
                } else if password.isEmpty {
                    focusedField = .passwordField
                } else {
                    handleLogin(username, password)
                }
            }
        }
    }
}

struct EmptyStateViewModifier<EmptyContent>: ViewModifier where EmptyContent: View {
    var isEmpty: Bool
    let emptyContent: () -> EmptyContent
    func body(content: Content) -> some View {
        if isEmpty {
            emptyContent()
        } else {
            content
        }
    }
}

extension View {
    func emptyState<EmptyContent>(_ isEmpty: Bool,
                                    emptyContent: @escaping () -> EmptyContent) -> some View where EmptyContent: View {
        modifier(EmptyStateViewModifier(isEmpty: isEmpty, emptyContent: emptyContent))
    }
}

Thanks for response, but it is not what I am looking for.

  1. Your solution is compliant only for iOS15 (due to using @FocusState), needs a solution for iOS14 and above.
  2. the TextField - is a single line input view, I need a multiline input view like UITextView or TextEditor.

I'll appreciate if any other suggestions you have.

Still not relying on UIKit directly you can still make this a pure SwiftUI implementation by using a SwiftUI TextEditor and FocusValue & FocusBinding for iOS 14+ to do what FocusState is doing at iOS 15+.

https://swiftwithmajid.com/2021/03/03/focusedvalue-and-focusedbinding-property-wrappers-in-swiftui/

iOS voiceover for multiline input field
 
 
Q