Reputation: 103
I'm writting a simple VAT calculator
I would like change the aspect of TextFields, focused one as white background and the others have grey background.
Event sending for Textfields seems to be when leave focus, so as i want to change color when enter focus, i've subclass NSTextField in FATextfield. Detect which Textfield as focus is OK.
After that, i would like to have a function that changes background according to the actual focused TextField.
I don't understand in my textFieldsLookUpdate function, view is not loaded and all FATextFields are nil ...
Thanx
My FATextField class :
import Cocoa
class FATextField: NSTextField {
var name: String = ""
override func mouseDown(with:NSEvent) {
let viewController:ViewController = ViewController()
viewController.textFieldClicked(FATextFieldclicked:name)
}
}
My View Controller :
import Cocoa
class ViewController: NSViewController {
var ligneBloquee: String = ""
var focusedTextField: String = "none" {
didSet {
textFieldsLookUpdate()
}
}
@IBOutlet weak var boutonRadioHt: NSButton!
@IBOutlet weak var boutonRadioTva: NSButton!
@IBOutlet weak var boutonRadioTtc: NSButton!
@IBOutlet weak var textFieldHt21: FATextField!
@IBOutlet weak var textFieldHt55: FATextField!
@IBOutlet weak var textFieldHt10: FATextField!
@IBOutlet weak var textFieldHt20: FATextField!
@IBOutlet weak var textFieldTva21: FATextField!
@IBOutlet weak var textFieldTva55: FATextField!
@IBOutlet weak var textFieldTva10: FATextField!
@IBOutlet weak var textFieldTva20: FATextField!
@IBOutlet weak var textFieldTtc21: FATextField!
@IBOutlet weak var textFieldTtc55: FATextField!
@IBOutlet weak var textFieldTtc10: FATextField!
@IBOutlet weak var textFieldTtc20: FATextField!
// MARK: - Fonctions de démarrage
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - dans "viewDidAppear on est sur que tous les éléménets de l'interface graphique sont initialisés...
override func viewDidAppear() {
super.viewDidAppear()
//textFieldHt20.window?.makeFirstResponder(textFieldHt20)
textFieldHt21.name = "textFieldHt21"
textFieldTva21.name = "textFieldTva21"
textFieldTtc21.name = "textFieldTtc21"
textFieldHt55.name = "textFieldHt55"
textFieldTva55.name = "textFieldTva55"
textFieldTtc55.name = "textFieldTtc55"
textFieldHt10.name = "textFieldHt10"
textFieldTva10.name = "textFieldTva10"
textFieldTtc10.name = "textFieldTtc10"
textFieldHt20.name = "textFieldHt20"
textFieldTva20.name = "textFieldTva20"
textFieldTtc20.name = "textFieldTtc20"
if isViewLoaded {
print ("View is loaded")
} else {
print ("View is not loaded")
}
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
// MARK: Action des éléments graphiques
@IBAction func boutonRadioClicked(_ sender: NSButton) {
if sender.title == "HT" {
ligneBloquee = "HT"
} else if sender.title == "TVA" {
ligneBloquee = "TVA"
} else {
ligneBloquee = "TTC"
}
print (ligneBloquee)
}
func textFieldClicked (FATextFieldclicked: String) {
print(FATextFieldclicked)
focusedTextField = FATextFieldclicked
}
private func textFieldsLookUpdate () {
if isViewLoaded {
print ("View is loaded")
} else {
print ("View is not loaded")
}
if textFieldHt21 == nil {
print ("textFieldHt21 is nil")
} else {
print ("textFieldHt21 is not nil")
}
}
@IBAction func FATextFieldEnter(_ sender: FATextField) {
//print(sender.name)
}
}
In Storyboard the TextFields are rightly set to FATextView
Upvotes: 0
Views: 75
Reputation: 103
In fact, after much research, the main thing that a newbie like me should know is that NSTextField inherits from NSControl.
While exploring NSControl I found:
/* The following category applies only to controls with editable text, like NSTextField.
*/
…
open func currentEditor() -> NSText?
…
optional func controlTextDidBeginEditing(_ obj: Notification)
optional func controlTextDidEndEditing(_ obj: Notification)
Changing the appearance of the NSTextField while editing does not require a subclass, the code below works just fine:
class ViewController: NSViewController, NSTextFieldDelegate {
@IBOutlet weak var textField1: NSTextField!
@IBOutlet weak var textField2: NSTextField!
@IBOutlet weak var label1: NSTextField!
@IBOutlet weak var label2: NSTextField!
var listOfTextfields: [NSTextField] = []
override func viewDidLoad() {
super.viewDidLoad()
textField1.delegate = self
textField2.delegate = self
textField1.isBezeled = false
textField2.isBezeled = false
listOfTextfields = [textField1, textField2]
textField1.window?.makeFirstResponder(textField1)
textField1.backgroundColor = NSColor.textBackgroundColor
whichElementAsFocus()
}
override var representedObject: Any? {
didSet {
}
}
// Function qui détermine quel élément à le focus
func whichElementAsFocus() {
for case let textField as NSTextField in self.view.subviews {
if textField.currentEditor() != nil {
textField.backgroundColor = NSColor.textBackgroundColor
} else {
textField.backgroundColor = NSColor.windowBackgroundColor
}
}
}
// Fonction qui se produit lorsque l'on débute la saisie
func controlTextDidBeginEditing(_ obj: Notification) {
whichElementAsFocus()
}
// Fonction qui se produit à chaque fois que l'on saisi un caractère
func controlTextDidChange(_ notification: Notification) {
/*
if let textField = notification.object as? NSTextField {
//print(textField.name)
//ICI fonction de mise à jour des contenus des autres textfield
}
*/
}
// Fonction qui se produit quand on sort d'un textfield
func controlTextDidEndEditing(_ notification: Notification) {
if let textField = notification.object as? NSTextField {
textField.backgroundColor = NSColor.windowBackgroundColor
}
}
}
The result :
Above the NSTextField being edited there is another NSTextField that is not being edited. Whether pressing the Tab key on the keyboard or clicking with the mouse, everything goes as expected.
Upvotes: 0
Reputation: 534885
The problem is actually in the previous line:
let viewController:ViewController = ViewController()
viewController.textFieldClicked(FATextFieldclicked:name)
So now you have created a ViewController instance — and you then call its textFieldClicked
method and you throw the view controller away. Which is fine, because it was always useless. The key fact is that this is not the right view controller. You don't want to create a new view controller: you want to find the actual view controller that already exists in your interface.
Upvotes: 1