1

The question is: how to focus on the TextEditor when the app launches.

I have seen several questions and possible answers about focus on SwiftUI views and elements, but nothing that I've tried worked so far. I also know that on the next version of Swift, supporting macOS Monterrey, focusing will be handled differently, however I am still stuck with an application for macOS Big Sur.

Essentially I have application with the typical three column view.

The left-most view is a list set as:

.listStyle(SidebarListStyle())

The middle one is another list with a list of the filenames I want to load, and the third view, the right most, is a TextEditor which shows the contents of the file loaded.

When the application launches the first item in the middle view gets automatically selected, and the contents of the file are loaded into the TextEditor. However, the focus is nowhere. I have to manually set the focus on the text editor with my mouse.

I have tried with .focusable() and tried creating other controls and set focus. But, how do I set the focus to be on the TextEditor when the app launches?

Thanks!

Edit - minimal reproducible example code as requested:

import SwiftUI

struct Mail: Identifiable, Hashable {
    let id = UUID()
    let date: Date
    let subject: String
    let body: String
    var isFavorited = false
}

final class MailStore: ObservableObject {
    @Published var allMails: [String: [Mail]] = [
        "Inbox": [ .init(date: Date(), subject: "Subject1", body: "Very long body...") ],
        "Sent": [ .init(date: Date(), subject: "Subject2", body: "Very long body...") ],
    ]
}

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .padding()
    }
}


struct Sidebar: View {
    @ObservedObject var store: MailStore
    @Binding var selectedFolder: String?
    @Binding var selectedMail: Mail?

    var body: some View {
        List {
            ForEach(Array(store.allMails.keys), id: \.self) { folder in
                NavigationLink(
                    destination: FolderView(
                        title: folder,
                        mails: store.allMails[folder, default: []],
                        selectedMail: $selectedMail
                    ),
                    tag: folder,
                    selection: $selectedFolder
                ) {
                    Text(folder).font(.headline)
                }
            }
        }.listStyle(SidebarListStyle())
    }
}

struct FolderView: View {
    let title: String
    let mails: [Mail]
    @Binding var selectedMail: Mail?

    var body: some View {
        List {
            ForEach(mails) { mail in
                NavigationLink(
                    destination: MailView(mail: mail),
                    tag: mail,
                    selection: $selectedMail
                ) {
                    VStack(alignment: .leading) {
                        Text(mail.subject)
                        Text(mail.date, style: .date)
                    }
                }
            }
        }.navigationTitle(title)
    }
}

struct MailView: View {
    let mail: Mail
    
    @State private var fullText: String = "This is some editable text..."

    var body: some View {
        VStack(alignment: .leading) {
            TextEditor(text: $fullText)
        }
    }
}



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

EDIT II

So, based on this, I need to hack a lot of code to make the TexEditor be focused. I guess it's not possible as of Big Sur, maybe for the next version of the OS, I can use focused.

Aleph
  • 465
  • 2
  • 12
  • 2
    Can you share a [mre] of your basic setup and what you’ve tried with focusable? – jnpdx Sep 30 '21 at 17:08
  • I sure can, let me add it shortly to the question, thank you. EDIT: by reproducible you want the whole code for each view? that's a TON of code, so, I need to remove things in a way that enables the code to still run.... – Aleph Sep 30 '21 at 17:10
  • @Aleph Read what it says for the link of [mre]. Just create a new project, and recreate the problem with the simplest code possible. We just need a really short example where we can copy & paste in the code without any other dependent code, so we can test & debug the problem. – George Sep 30 '21 at 17:15
  • added the code. It's very evident what it does. You can reproduce it with any standard 3 column navigation view on Xcode. Also, this is essentially how to focus the TextEditor, that's all. Nothing else. it should be very reproducible with any code. – Aleph Sep 30 '21 at 17:22
  • @Aleph That code still depends on a lot of things, such as `NoteItem`, `DataModel`, and more. If we can get a running example, we can help. Start a new project from scratch and recreate your problem because that will be the exact code which is needed. – George Sep 30 '21 at 17:26
  • @George nothing depends on any code, you can create literally a single view with a text editor, how so I set the focus on it? Want me to do that? Fine. Code will be added shortly. – Aleph Sep 30 '21 at 17:33
  • @George full code of a mockup added. – Aleph Sep 30 '21 at 17:37
  • So, based on [this](https://stackoverflow.com/questions/56507839/swiftui-how-to-make-textfield-become-first-responder), I need to hack a lot of code to make the TexEditor be focused. I guess it's not possible as of Big Sur, maybe for the next version of the OS, I can use `focused`. – Aleph Sep 30 '21 at 18:30
  • Does calling the focus function not work using .onAppear? – DaWiseguy Sep 30 '21 at 18:40
  • There is no focus function. – Aleph Sep 30 '21 at 18:41
  • I would just copy and paste the code you shared for it to become first responder and call it on the onAppear. For swift that's definitely not 'a lot' of code anyways. – DaWiseguy Sep 30 '21 at 18:44
  • Thank you @DaWiseguy but I haven't found a way to make anything first responder with swiftUI. If you have a example code, could please post it.I was asked for code so people can work on, it want to all request code, so I can learn. – Aleph Sep 30 '21 at 18:48
  • I thought you were using iOS 13 objects, but looks like TextEditor is iOS 14+ this link looks like it may help. But for my apps, I have used a custom focus function with "first Responder" like in your example. https://developer.apple.com/forums/thread/681962 – DaWiseguy Sep 30 '21 at 18:50
  • This macOS (Big Sur), not iOS. @DaWiseguy. I tried that code before and Xcode error says not available. – Aleph Sep 30 '21 at 18:52
  • Also, @DaWiseguy this is not for Monterrey, it's for Big Sur, so `focused` or `prefersDefaultFocus` does not work. – Aleph Sep 30 '21 at 18:55

0 Answers0