Swift macOS:视图未加载且 IBOulet 在视图控制器中为零

发布于 2025-01-12 01:33:47 字数 3933 浏览 0 评论 0原文

我正在写一个简单的增值税计算器 输入图片此处描述

我想更改 TextFields 的外观,将焦点集中为白色背景,其他为灰色背景。

文本字段的事件发送似乎是在离开焦点时进行的,因此当我想在进入焦点时更改颜色时,我在 FATextfield 中对 NSTextField 进行了子类化。检测哪个文本字段作为焦点是可以的。

之后,我想要一个根据实际聚焦的 TextField 更改背景的功能。

我不明白我的 textFieldsLookUpdate 函数,视图未加载,所有 FATextField 均为 nil ...

感谢

我的 FATextField 类:

import Cocoa

class FATextField: NSTextField {
    
    var name: String = ""
    
    override func mouseDown(with:NSEvent) {
        let viewController:ViewController = ViewController()
        viewController.textFieldClicked(FATextFieldclicked:name)
    }
    
}

我的视图控制器:

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)
    }
}

在 Storyboard 中,TextFields 正确设置为 FATextView

I'm writting a simple VAT calculator
enter image description here

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱你是孤单的心事 2025-01-19 01:33:47

问题实际上出在上一行:

    let viewController:ViewController = ViewController()
    viewController.textFieldClicked(FATextFieldclicked:name)

所以现在您已经创建一个 ViewController 实例 - 然后调用它的 textFieldClicked 方法,然后扔掉视图控制器< /em>.这很好,因为它总是没用。关键事实是这不是正确的视图控制器。您不想创建一个视图控制器:您希望找到实际视图控制器< em>已经存在于您的界面中。

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.

情徒 2025-01-19 01:33:47

事实上,经过大量研究,像我这样的新手应该知道的主要事情是 NSTextField 继承自 NSControl。

在探索 NSControl 时,我发现:

/* 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)

编辑时更改 NSTextField 的外观不需要子类,下面的代码工作得很好:

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
        }
    }
}

结果:

在此处输入图像描述

正在编辑的 NSTextField 上方有另一个未编辑的 NSTextField存在编辑。
无论是按键盘上的 Tab 键还是用鼠标单击,一切都会按预期进行。

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 :

enter image description here

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文