As a hobby project, I'm developing a SwiftUI app targeted for macOS.
I have a CoreData entity (let's call it Sample
) with a String
property called title
.
In my main view (SamplesView
) I'm displaying a List
of Sample
s, and I want title
s be editable directly from the list. For that, I've made a sub-view (SampleRowView
) with a TextField
, and I'm displaying this sub-view in the List
using ForEach
.
It works and looks okayish. Though, I can edit the title
only if I click directly on the TextField
's text (point 1 on the screenshot). If I click on the "empty" part of the TextField
(f.e. point 2) it does not respond. I thought that the shape of the TextField
is limited somehow by the length of its text, but as visible on the screenshot, TextField
occupies the whole row.
Appreciate any help and ideas about how to make the TextField
respond to click on its any point, not only on the text.
// "Sample" is a CoreData entity
public class Sample: NSManagedObject {
//...
@NSManaged public var title: String
}
// This is the main view
struct SamplesView: View {
@FetchRequest(...)
var samples: FetchedResults<Sample>
var body: some View {
VStack {
List {
ForEach(samples) { sample in
SampleRowView(sample: sample)
}
.onDelete(perform: deleteSample)
}
}
}
}
// List rows with editable Sample's title
struct SampleRowView: View {
@ObservedObject var sample: Sample
var body: some View {
TextField("", text: $sample.title)
}
}
Update:
The problem is the same even on the fresh project. Also, if I change TextField
with TextEditor
the behavior is kinda expected.
Digging a bit more into it: TextField inside a List in SwiftUI on macOS: Editing not working well
Editable TextField in SwiftUI List
SwiftUI make ForEach List row properly clickable for edition in EditMode
I've found that it seems to be a bug in SwiftUI, and for now the only solution is to somehow replace the List
with ScrollView
with custom item moving and deletion. This is sad.
import SwiftUI
struct Sample: Identifiable {
let id: Int
var title: String
init(id: Int) {
self.id = id
self.title = "Sample \(id)"
}
}
struct TestView: View {
@State var samples = [Sample(id: 1), Sample(id: 2)]
var body: some View {
List {
ForEach($samples) { $sample in
TextField("", text: $sample.title) // .textFieldStyle(.squareBorder) -- doesn't help
// TextEditor(text: $sample.title) // This works as expected
}
}
}
}
@main
struct SampleApp: App {
var body: some Scene {
WindowGroup {
TestView()
}
}
}
I'm using XCode Version 13.2.1, Swift 5, MacOS deployment target 11.6.