如何实时检查NSTextField - Swift OS X

6

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

6个回答

9
  1. Conforms ViewController to protocol NSTextDelegate.
  2. Assign ViewController as Delegate for TextField.
  3. Implement controlTextDidChange method.

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

感谢提供代码。稍后会尝试。我该如何检测编辑过的标签(可能会有两个)? - iProgram
使用标签来识别特定的控件。在Interface Builder中设置标签值。 - madmir
1
代码需要继承自NSTextFieldDelegate而不是NSTextDelegate。您还需要将文本字段的委托设置为self。 - iProgram
1
你只需在AppDelegate中创建一个方法,我建议在ViewController中完成它。 - madmir
ViewController之前没有在编辑中,这就是为什么我不能做它的原因。 - iProgram
我不得不在ViewController中添加NSTextFieldDelegate,以便接收controlTextDidChange通知。 - coachcal

4

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)

}

2

我知道这个问题已经在一段时间前得到了解答,但是我最终在Swift 3(不幸的是它不适用于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)")
}

希望这能帮助其他人。

1
以上的答案对于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 中的每个函数,只需将该方法放在扩展子句中即可。

1
嗨!我认为这个答案很有帮助。但是它漏掉了一步,记得将 "textfield.delegate = self" 放入你的 ViewController 中(否则你的 textfield 将不会向你的 ViewController 报告更改)。 - user3064009
是的,你说得对,谢谢。如果你想进行编辑,可以进行,但这是一种常识。 - cheesey
@user3722523 你是什么意思?我在哪里提到了那个? - cheesey

0
//If you want to trim Ex: Email ID, please use the below code.

class ViewController: NSViewController {

@IBOutlet weak var emailTextField: NSTextField!

override func viewDidLoad() {
    super.viewDidLoad()
    emailTextField.delegate = self
  }
}

extension ViewController : NSTextFieldDelegate {
func controlTextDidBeginEditing(_ obj: Notification) {
    print(#function)
}

func controlTextDidEndEditing(_ obj: Notification) {
    print(#function)
}

func controlTextDidChange(_ obj: Notification) {
    print(#function)
    if let textField = obj.object as? NSTextField {
        let givenText = textField.stringValue
        
        //Here you add other types of white space
        let possibleWhiteSpace: NSArray = [" ", "\t", "\n\r", "\n","\r"]
        var string: String = givenText as String
        possibleWhiteSpace.enumerateObjects { (whiteSpace, idx, stop) -> Void in
            string = string.replacingOccurrences(of: whiteSpace as! String, with: "") as String
        }
        
        print(string)
        emailTextField.stringValue = string as String
    }
 }
}

0
extension String {
  func removeAllTypesOfWhiteSpaces(_ inputString : String) -> String {
    //Here you add other types of white space
    let possibleWhiteSpace: NSArray = [" ","\t", "\n\r", "\n","\r"]
    var outputStr: String = inputString as String
    possibleWhiteSpace.enumerateObjects { (whiteSpace, idx, stop) -> Void in
        outputStr = outputStr.replacingOccurrences(of: whiteSpace as! String, with: "") as String
    }
    return outputStr
  }
}

extension LoginViewController : NSTextFieldDelegate {
  func controlTextDidChange(_ obj: Notification) {
    if let textField = obj.object as? NSTextField {
        let givenText = textField.stringValue
        let resultStr = givenText.removeAllTypesOfWhiteSpaces(givenText)
        textField.stringValue = resultStr as String
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接