0

I check for and remove spaces from a NSTextField in controlTextDidEndEditing, but these changes are not reflected in the cocoa bindings (the CoreData entry is not updated). The NSTextField is updated, but if you click out of the entry and go back in the spaces come back. How can I trigger the bound object to update the data store?

I am bound to .value for the NSTextField, I even tried setting .objectValue to .stringValue after the update, but it didn't work.

override func controlTextDidEndEditing(obj: NSNotification) {
    Swift.print("editing is done now")

    let textField:NSTextField = obj.object as! NSTextField

    //if last character is a space remove it.
    while textField.stringValue.characters.last == " "
    {
        Swift.print("last char is a space")
        textField.stringValue.removeAtIndex(textField.stringValue.endIndex.predecessor())

    }

    //save to database now.
    let dele:AppDelegate = NSApplication.sharedApplication().delegate as! AppDelegate
    dele.saveAction(nil)

}
glenstorey
  • 5,134
  • 5
  • 39
  • 71

1 Answers1

1

textField.stringValue is not a reference type. You might assign the value back to the text field.

There is a more convenient way to trim strings

override func controlTextDidEndEditing(obj: NSNotification) {
  Swift.print("editing is done now")

  let textField = obj.object as! NSTextField
  let string = textField.stringValue
  textField.stringValue = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())

  //save to database now.
  let dele:AppDelegate = NSApplication.sharedApplication().delegate as! AppDelegate
  dele.saveAction(nil)
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thanks for the .stringByTrimming... refinement. Can you clarify what you mean when you say assign the value back to the text field? – glenstorey Feb 28 '16 at 17:59
  • 1
    You retrieve the string value from the text field like a copy. When you change the string it actually doesn't change the text field. You need to assign the value back to the `stringValue` property of the text field. – vadian Feb 28 '16 at 18:03
  • If I understand what you're saying using a IBOutlet to set the stringValue to after trimming should work, but it doesn't - adding the line phraseTextField.stringValue = textField.stringValue (where phraseTextField is an IBOutlet to the text field) doesn't change anything. Also - if it is a copy, why does the interface update, but the bound managed object doesn't? – glenstorey Feb 28 '16 at 18:07
  • Have you checked the option `continuously updates value` in the bindings Inspector? – vadian Feb 28 '16 at 18:14
  • No - but when I check it I still have the same problem. – glenstorey Feb 29 '16 at 16:20
  • Were you suggesting I directly update the managed object? (I wasn't sure what you meant about .stringValue not being a reference type). Completely ignoring the binding in this case and updating the managed object worked, but it feels like I'm circumventing bindings. let firstObject = phraseArrayController.selectedObjects.first as? Phrase firstObject?.string = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) – glenstorey Feb 29 '16 at 16:33
  • In this case I'd recommend to update the managed object directly and drop the bindings. – vadian Feb 29 '16 at 17:00