【问题标题】:How to live check a NSTextField - Swift OS X如何实时检查 NSTextField - Swift OS X
【发布时间】:2016-01-09 14:15:06
【问题描述】:

我目前正在制作一个用 Swift 编写的 OS X 应用程序。我想要做的是当用户在NSTextField 中输入文本时,我想运行一个检查值并将其添加到标签的函数。我将如何快速做到这一点?

【问题讨论】:

    标签: macos label swift2 nstextfield


    【解决方案1】:
    1. 符合ViewController 协议NSTextDelegate
    2. ViewController 指定为TextField 的代表。
    3. 实现controlTextDidChange 方法。

      import Cocoa
      
      @NSApplicationMain
      class AppDelegate: NSObject, NSApplicationDelegate, NSTextFieldDelegate {
      
          @IBOutlet weak var window: NSWindow!
          @IBOutlet weak var textField: NSTextField!
          @IBOutlet weak var label: NSTextField!
      
      
          func applicationDidFinishLaunching(aNotification: NSNotification)
          {
              textField.delegate = self
          }
      
          override func controlTextDidChange(notification: NSNotification)
          {
              let object = notification.object as! NSTextField
              self.label.stringValue = object.stringValue
          }
      
          func applicationWillTerminate(aNotification: NSNotification) {
              // Insert code here to tear down your application
          }
      }
      

    在 ViewController 中:

    import Cocoa
    
    class ViewController: NSViewController, NSTextDelegate {
    
       @IBOutlet weak var label: NSTextField!
       @IBOutlet weak var label2: NSTextField!
       @IBOutlet weak var textField: NSTextField!
       @IBOutlet weak var textField2: NSTextField!
    
       override func viewDidLoad() {
          super.viewDidLoad()
       }
    
       override func controlTextDidChange(notification: NSNotification) {
          if let txtFld = notification.object as? NSTextField {
             switch txtFld.tag {
             case 201:
                self.label.stringValue = txtFld.stringValue
             case 202:
                self.label2.stringValue = txtFld.stringValue
             default:
                break
             }
          }
       }
    }
    

    【讨论】:

    • 感谢您的代码。稍后会尝试。我将如何检测已编辑的标签(我可能一次有 2 个)
    • 使用标签,允许您识别特定控件。在 Interface Builder 中设置的标记值
    • 代码需要继承自 NSTextFieldDelegate 而不是 NSTextDelegate。您还需要将文本字段委托设置为 self。
    • 你只需在 AppDelegate 中创建一个方法,我提出在 ViewController 中进行
    • ViewController 之前不在编辑中,这就是我做不到的原因。
    【解决方案2】:

    swift 5 xcode 10

    //TODO: move oin a better place?
    extension NSTextField{ func controlTextDidChange(obj: NSNotification){} }
    
    
        class TracksController:NSViewController,
            NSTextFieldDelegate
        {
    ...
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            //Search bar:
            self.searchBar.delegate = self
    
            NotificationCenter.default.addObserver(self,
                                                   selector: #selector(controlTextDidChange(_:)),
                                                   name: NSTextView.didChangeSelectionNotification,
                                                   object: nil)
    
        }
    

    //MARK: NSTextFieldDelegate

    func controlTextDidChange(_ obj: Notification)
    {
        guard let object = obj.object as? NSTextView else{
            return
        }
    
    
        let delegate = object.delegate
        guard  let searchField = delegate as? NSSearchField else {
            return
        }
    
        let text = searchField.stringValue
        print(text)
    
    }
    

    【讨论】:

      【解决方案3】:

      我知道它已经在不久前得到了回答,但我最终在 Swift 3 中找到了这个适用于 macOS 的解决方案(不幸的是,它不适用于 Swift 4),它会在文本字段被点击内部以及每次击键时发出通知。

      将此委托添加到您的班级:-

      NSTextFieldDelegate
      

      在 viewDidLoad() 中

      NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: Notification.Name.NSTextViewDidChangeSelection, object: nil)
      

      然后添加这个函数:-

          func textDidChange(_ notification: Notification) {
              print("Its come here textDidChange")
              guard (notification.object as? NSTextView) != nil else { return }
              let numberOfCharatersInTextfield: Int = textFieldCell.accessibilityNumberOfCharacters()
              print("numberOfCharatersInTextfield = \(numberOfCharatersInTextfield)")
      }
      

      希望这对其他人有所帮助。

      【讨论】:

        【解决方案4】:

        上面的答案不适用于 swift 4 所以,

        Swift 4 解决方案

        过程基本相同,但您只需将一些功能扩展到 NSTextfield 类。我们必须这样做的原因是,像 controlTextDidChange: 这样的委托协议方法实际上根本不存在,因为 Objective-c 代码的旧设计不能很好地映射到 swift。 Objective-c 中的 NSTextFieldDelegate 是一个非正式的协议,和 swift 中的扩展是一样的。

        示例

        extension NSTextField{ func controlTextDidChange(obj: NSNotification){} }
        
        class SomeViewController:NSViewController,NSTextFieldDelegate {
        
        override func controlTextDidChange(_ obj: Notification)
        {
            let object = obj.object as! NSTextField
            let value = object.stringValue
            print(value)
        }
        

        对于每个函数,你想从 NSTextFieldDelegate 中使用,只需将方法放在扩展子句中。

        【讨论】:

        • 嗨!我认为这个答案很有帮助。但是它错过了一步,请记住将“textfield.delegate = self”放入您的 ViewController(否则您的文本字段不会向您的 ViewController 报告更改)。
        • 是的,你说得对,谢谢。如果你想进行编辑,你可以,但这是给定的。
        • @user3722523 你什么意思?我在哪里提到?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-30
        • 2014-07-08
        • 1970-01-01
        • 2012-01-10
        • 1970-01-01
        相关资源
        最近更新 更多