2

I need to set a character limit for TextFields. I followed this answer and I was able to set a limit. But now when I press enter all characters are wiped out. What went wrong ?

- (BOOL)isPartialStringValid:(NSString *__autoreleasing *)partialStringPtr
       proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
              originalString:(NSString *)origString
       originalSelectedRange:(NSRange)origSelRange
            errorDescription:(NSString *__autoreleasing *)error {
    if ([*partialStringPtr length] > maxLength)
        return NO;
    else
        return YES;
}

- (NSString *)stringForObjectValue:(id)obj {
    return (NSString*) obj;
}

- (BOOL)getObjectValue:(out __autoreleasing id *)obj
             forString:(NSString *)string
      errorDescription:(out NSString *__autoreleasing *)error {
    return YES;
}

- (NSAttributedString *)attributedStringForObjectValue:(id)obj
                                 withDefaultAttributes:(NSDictionary *)attrs {
    return (NSAttributedString*) obj;
}
Community
  • 1
  • 1
user88975
  • 1,618
  • 3
  • 19
  • 29

3 Answers3

5

How about setting yourself as delegate of the NSTextField an implement this delegate method?

- (void)textDidChange:(NSNotification *)aNotification

There you could check if the text is too long and then cut it if this is the case.

NSTextField *textField = (NSTextField *)[aNotification object];
if ([textField.stringValue length] > maxLength)
{
    textField.stringValue = [textField.stringValue substringWithRange:NSMakeRange(0,maxLength)];
}
Michael Knudsen
  • 629
  • 1
  • 7
  • 23
  • Yes ended up using `controlTextDidChange` But was keen on doing it using NSFormatter class instead which seemed to me like the right thing. – user88975 Feb 26 '14 at 14:32
  • Check this Thread for NSFormatter (http://stackoverflow.com/questions/827014/how-to-limit-nstextfield-text-length-and-keep-it-always-upper-case) – Jeba Moses May 22 '17 at 07:55
2

Swift 5 in viewDidLoad call the delegate

viewDidload(){
    yourTextFiled.delegate = self
}

extension NSTextField{
    func controlTextDidChange(obj: NSNotification){}
}
extension YourViewController:NSTextFieldDelegate{
    func controlTextDidChange(_ obj: Notification)
    {
        let object = obj.object as! NSTextField
        if object.stringValue.count > yourTextLimit{
        object.stringValue = String(object.stringValue.dropLast())
    }
}
Awais Mobeen
  • 733
  • 11
  • 19
cheesey
  • 516
  • 7
  • 18
0
//  NSTextFieldCharLimit+Extension.swift

import Foundation

class TextFieldCharLimit: Formatter {
var maxLength: UInt

init(maxLength: UInt) {
    self.maxLength = maxLength
    super.init()
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

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 AnyObject
    return true
}

override func isPartialStringValid(_ partialStringPtr: AutoreleasingUnsafeMutablePointer<NSString>, proposedSelectedRange proposedSelRangePtr: NSRangePointer?, originalString origString: String, originalSelectedRange origSelRange: NSRange, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
    
    if partialStringPtr.pointee.length > maxLength {
        let myRange = NSRange(location: 0, length: Int(maxLength))
        partialStringPtr.pointee = (partialStringPtr.pointee as NSString).substring(with: myRange) as NSString
        return false
    }
    
    return true
}

override func attributedString(for obj: Any, withDefaultAttributes attrs: [NSAttributedString.Key : Any]? = nil) -> NSAttributedString? {
    return nil
 }
}

//Need to call

usernameTextField.formatter = TextFieldCharLimit(maxLength: 6)
Mannam Brahmam
  • 2,225
  • 2
  • 24
  • 36