`focusable()` broken for views that are not already focusable

This is taken from a completely fresh multiplatform SwiftUI project. I want to be able to make a custom view focusable, so I tried testing with a Text view but it's not working. Isn't that the whole point of .focusable() to declare an arbitrary view focusable? If that's the case, then why isn't it working in the below code:

import SwiftUI

struct ContentView: View {
    @FocusState private var focusedItem: Optional<FocusedItem>

    var body: some View {
        VStack {
            Text("Test")
                .focusable(true)
                .focused($focusedItem, equals: .two)

            Button("Toggle Focus") {
                self.focusedItem=(self.focusedItem == nil) ? .two : nil
                DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                      
                    // Always prints `nil`.
                    print(self.focusedItem)
                }
            }
        }
    }
    
    enum FocusedItem {
        case one, two
        func other() -> FocusedItem {
            switch self {
            case .one: return .two
            case .two: return .one
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

  • Using a Text view is not supported with focus. Focus is used for setting the input focus (firstResponder) for input-oriented controls like TextField, TextEditor etc. Read the documentation first, it usually helps.

  • I did: “Specifies if the view is focusable.”. Where in the documentation did you read that it’s for “input-oriented” controls?

Add a Comment

Replies

Your code modified to use a TextField instead of a Text view.

import SwiftUI



struct ContentView: View {

    @FocusState private var focusedItem: Optional<FocusedItem>

    @State var inputname: String = ""

    

    var body: some View {

        VStack {

            

            TextField("Test", text: $inputname)

            #if os(macOS)

                .focusable(true)

            #endif

                .focused($focusedItem, equals: .two)



            Button("Toggle Focus") {

                self.focusedItem=(self.focusedItem == nil) ? .two : nil

            }.onChange(of: focusedItem) { newValue in

                // Always prints `nil`.

                print(newValue as Any)

            }

        }

    }

    

    enum FocusedItem: Equatable {

        case one, two

        func other() -> FocusedItem {

            switch self {

            case .one: return .two

            case .two: return .one

            }

        }

    }

}



struct ContentView_Previews: PreviewProvider {

    static var previews: some View {

        ContentView()

    }

}