Using TextField:text:selection crashes on macOS

I am trying out the new TextField selection ability on macOS but it crashes in various different ways with extremely large stack traces. Looks like it is getting into re-entrant function calls.

A similar problem is described on the SwiftUI forums with no responses yet.

Here is my simple example

struct ContentView: View {
  @State private var text: String = ""
  @State private var selection: TextSelection?
  
  var body: some View {
    TextField("Message", text: $text, selection: $selection)
      .padding()
  }
}

Setting text to a value like "Hallo World" causes an instant crash as soon as you start typing in the TextField.

Setting text empty (as in example above) lets you edit the text but as it crashes as soon as you commit it (press enter).

Any workarounds or fixes?

Answered by DTS Engineer in 805229022

There isn't a workaround for the issue at the moment. Please test on the latest beta build (macOS Sequoia 15.1 Beta 5) and verify if you're still able to reproduce the issue.

Also, please file a bug report via Feedback Assistant. Once you open the bug report, please post the FB number here for my reference.

If you have any questions about filing a bug report, take a look at Bug Reporting: How and Why?

Accepted Answer

There isn't a workaround for the issue at the moment. Please test on the latest beta build (macOS Sequoia 15.1 Beta 5) and verify if you're still able to reproduce the issue.

Also, please file a bug report via Feedback Assistant. Once you open the bug report, please post the FB number here for my reference.

If you have any questions about filing a bug report, take a look at Bug Reporting: How and Why?

Same issue in macOS 15.0.1. Pelease fix it ASAP. Thank you!

Follow-up, but related question. I expanded my demo, playing with TextField(text:selection) to understand it and found that the selection changes before the text does.

Below is my expanded file. I tried to print the selection underneith the TextField but this code crashes. I've added print statements to debug and found that the selection is not valid for the value of text when I call toString. Is this normal?

I found that using the onChange event on the selection works correctly but I see this as a workaround. It means there is currently no way to just print the selection (current state) with the corresponding text (same state) in the view, or am I missing something?

struct ContentView: View {
  @State private var selection: TextSelection?
  @State private var text: String = ""
  
  var body: some View {
    VStack {
      TextField("Message", text: $text, selection: $selection)
//        .onChange(of: selection) {
//          if let selection = selection.take() {
//            if case let .selection(range) = selection.indices {
//              print("Selection in \(text): \(toString(selection: selection))")
//              print("Selected text: '\(text[range])'")
//            }
//          }
//        }
      
      Text("Selection in \(text): \(toString(selection: selection))")
    }
    .padding()
  }
  
  func toString(selection: TextSelection?) -> String {
    guard let selection else { return "None" }
    
    print("Printing indices in '\(text)'")
    
    switch selection.indices {
    case .selection(let range):
      let lower = range.lowerBound.utf16Offset(in: text)
      let upper = range.upperBound.utf16Offset(in: text)
      return "\(lower) - \(upper)"
    
    case .multiSelection(let rangeSet):
      return "Multi selection \(rangeSet)"
      
    @unknown default:
      fatalError("Unknown selection")
    }
  }
}
Using TextField:text:selection crashes on macOS
 
 
Q