Os X Nstextfield Validation

os x nstextfield validation

Generic solution (work with or without bindings) One way of dealing with this is based on the response here

Basically you use the controlTextDidChange(notification:) delegate method of NSTextField and you implement your validation code in it.

 override func controlTextDidChange (notification: NSNotification) {
guard let textField = notification.object as? NSTextField else { return }

// test here, replace the dummy test below with something useful
if textField.stringValue != "expected value" {
myTextFieldOutlet.backgroundColor = NSColor.red
myErrorLabelOutlet.stringValue = "Error !!!"
} else {
// everything OK, reset the background color and error label to the normal state
....
}
}

Obviously myTextFieldOutlet is an outlet linked to your text field and myErrorLabelOutlet is an outlet to a conveniently placed label used to show errors (blank if no error should be presented)

Bindings oriented solution Be sure Validates immediately is selected in Interface Builder and implement the following method in the class where the binding is made (Tuning View Controller in your example)

override func validateValue(_ ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?>, forKey inKey: String) throws {
// test here, replace the dummy test below with something useful
if roll_rate > 10.0 {
throw NSError(domain: "your-domain", code: 100, userInfo: [NSLocalizedDescriptionKey: "Error, roll rate too high"])
}
}

When the error is thrown, the user will be presented with the standard sheet announcing the error and the option to cancel the change or correct it.

If Continuously updates value is selected in Interface Builder the method above will be called for each keystroke in the text field, otherwise only after pressing Enter or loosing focus.

Note: For a full understanding on how updating values through bindings work, including what Validates immediately does, see the docs here.

How to live check a NSTextField - Swift OS X

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

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

How to validate NSTextField content in a modal dialog

clicking the OK button does not trigger the field's formatting and thus the alert does not show.

Call makeFirstResponder(nil) to force formatting of the contents. makeFirstResponder returns false if the text field refuses to resign its first responder status.

@IBAction func okAction(_ sender: Any) {
if let window = view.window,
window.makeFirstResponder(nil) {
dismiss(self)
}
}

How can I make a NSTextfield with left or right indicator for validation?

A text field control is a view where the drawing is all done with an NSTextFieldCell. What you'd need to do is subclass NSTextFieldCell, and customize the drawing. Look at NSCell's API and you'll see there's a drawWithFrame:inView: method which is what does all of the drawing for the entire field. Various other methods of NSCell are used in this process.

Unfortunately some of how the drawing is done is a bit private and not eeeasily fiddled with, but the main thing is drawWithFrame:inView: will draw the background and then call drawInteriorWithFrame:inView: to draw the text. Off the top of my head, I can't remember if NSTextFieldCell uses titleRectForBounds: to determine what the text's bounds are, but I'm pretty sure it is. So you could override that to return a narrower rectangle, leaving room to either draw the validation icon with the cell itself, or use a subview.

Additionally, you'll need to adjust the bounds in which the NSTextView field editor draws and edits the text, otherwise when you view the field while it is not first responder it will look fine, but when you edit the field's text it will overlap the icon. For that you may need to adjust the frame given to editWithFrame:inView:editor:delegate:event:.

It's always a bit finicky to tweak text fields because it takes a while to find all the methods and code paths involved, but that's the gist of what you need to do.

ViewController + Storyboard setting up validation with controlTextDidChange

I think the samples you're following are a bit out-of-date.
Try...

    override func controlTextDidChange(_ notification: Notification) {

...as the function definition for your method in your NSTextFieldDelegate.

Force a NStextField to only accept Hex values

See this answer for a much better explanation, but it would be something like:

- (void)controlTextDidChange:(NSNotification *)aNotification {
NSError *outError;
NSControl *textField = [aNotification object];
NSString *myText = [textField stringValue];

// check if myText is 0-9 or a-f, do something with it if its not hex.

// update the NSNextField with the validated text
[postingObject setStringValue:myText];
}

Form validation issue in macOS app

You can have NSTextField and NSSecureTextField in the same array. This is indeed an easy way to find the empty ones.

let tf = NSTextField()
let stf = NSSecureTextField()
let tf2 = NSTextField()
tf2.stringValue = "some text"

let all = [tf, stf, tf2]

let emptyTextFields = all.filter { $0.stringValue.isEmpty }

Also in your example you can't use commas to group conditions in if, you have to use &&:

if tf.stringValue.isEmpty && stf.stringValue.isEmpty && tf2.stringValue.isEmpty {
// do something
}

but this is not a good solution, better use the array and filter.



Related Topics



Leave a reply



Submit