1

I am newbie to MAC development. If answer is already explained anywhere, please add link in comments. I will remove the question in that case.

Currently, if textfield length reaches maximum count I'm showing an alert.But, still the last entered character is present in textfield so user needs a backspace.

I also tried using NSFormatter, but failed.

//CODE

override func controlTextDidChange(_ obj: Notification) {
  if let textField = obj.object as? NSTextField {
     if textField.stringValue.count > x {
         // display alert
     }
  }
}

What I am expecting is that user should enter text, but text should not be displayed. Instead of an alert, text entry shouldn't be allowed like we achieve in web.

Thanks in advance.

aleclarson
  • 18,087
  • 14
  • 64
  • 91
  • 1
    Possible duplicate of [How to limit NSTextField text length and keep it always upper case?](https://stackoverflow.com/questions/827014/how-to-limit-nstextfield-text-length-and-keep-it-always-upper-case) – Willeke Feb 08 '19 at 09:22
  • @Willeke Thanks man. But i want to achieve this in Swift. – Maneesh Aucharla Feb 08 '19 at 09:56

1 Answers1

2

At its simplest, all you need is to subclass Formatter and override 3 methods:

class MyFormatter: Formatter {
    var maxLength = Int.max

    override func string(for obj: Any?) -> String? {
        return obj as? String
    }

    override func getObjectValue(_ obj: AutoreleasingUnsafeMutablePointer<AnyObject?>?, for string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
        obj?.pointee = string as NSString
        return true
    }

    override func isPartialStringValid(_ partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>?, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
        return partialString.count <= maxLength
    }
}

Then set the formatter for your textfield:

let formatter = MyFormatter()
formatter.maxLength = 10

textField.formatter = formatter

This is enough to guard against users typing in more than 10 characters or paste in strings that are long than 10 characters. If you want more advanced features like taking the first 10 characters when pasting in a long string, you should override isPartialStringValid(_:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:).

Code Different
  • 90,614
  • 16
  • 144
  • 163
  • @ Code Different That really works. Cheers to you. Also i tried this in another way .. var str:String = textField.stringValue for char in str.reversed(){ if str.count != xxx { str = String(str.dropLast()) } } textField.stringValue = str – Maneesh Aucharla Feb 25 '19 at 07:48