1

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 Samples, and I want titles 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.

Screenshot of the list

// "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.

s303
  • 23
  • 3
  • The code you posted does not appear to have this problem. There must be something else, not shown, causing the problem. If you click to the right of the text, the insertion point goes to the end of the text. – Yrb Mar 20 '22 at 21:11
  • 1
    I can replicate your issue. It works for me if you add to your `TextField`, `.textFieldStyle(.squareBorder)` or `.roundedBorder` – workingdog support Ukraine Mar 20 '22 at 23:27
  • Thanks for the suggestions, but unfortunately neither of these helps. I even created a new project and the behavior is the same. (XCode Version 13.2.1) – s303 Mar 21 '22 at 07:50
  • FYI, your new example code with the `.textFieldStyle(.squareBorder)` works well for me, on macos 12.3, using xcode 13.3, targets ios 15 and macCatalyst 12 and also macOS 12.3 only. It seems to be different (not working) on older systems, such as macos 11.6. – workingdog support Ukraine Mar 21 '22 at 08:38
  • Adding .squareBorder is also working for me. However, I don't like the style it creates. ;) – alex.bour Feb 01 '23 at 14:08

1 Answers1

0

You could try to add

.contentShape(Rectangle())

to your View element.

I use it along with Text()-Instances which allows me to accept clicks not only on the written part of the View element, but everywhere within its bounds.

Sili
  • 26
  • 4