Set the maximum character length of a UITextField

前端 未结 30 1460
难免孤独
难免孤独 2020-11-22 02:27

How can I set the maximum amount of characters in a UITextField on the iPhone SDK when I load up a UIView?

相关标签:
30条回答
  • 2020-11-22 02:41

    To make it work with cut & paste of strings of any length, I would suggest changing the function to something like:

    #define MAX_LENGTH 20
    
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
        {
            NSInteger insertDelta = string.length - range.length;
    
            if (textField.text.length + insertDelta > MAX_LENGTH)
            {
               return NO; // the new string would be longer than MAX_LENGTH
            }
            else {
                return YES;
            }
        }
    
    0 讨论(0)
  • 2020-11-22 02:42

    There is generic solution for setting max length in Swift. By IBInspectable you can add new Attribute in Xcode Attribute Inspector.

    import UIKit
    private var maxLengths = [UITextField: Int]()
    extension UITextField {
    
        @IBInspectable var maxLength: Int {
            get {
                guard let length = maxLengths[self]
                else {
                    return Int.max
                }
                return length
            }
            set {
                maxLengths[self] = newValue
                addTarget(
                    self,
                    action: Selector("limitLength:"),
                    forControlEvents: UIControlEvents.EditingChanged
                )
            }
        }
    
        func limitLength(textField: UITextField) {
            guard let prospectiveText = textField.text
                where prospectiveText.characters.count > maxLength else {
                    return
            }
            let selection = selectedTextRange
            text = prospectiveText.substringWithRange(
                Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
            )
            selectedTextRange = selection
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 02:42

    I give a supplementary answer based on @Frouo. I think his answer is the most beautiful way. Becuase it's a common control we can reuse.

    private var kAssociationKeyMaxLength: Int = 0
    
    extension UITextField {
    
        @IBInspectable var maxLength: Int {
            get {
                if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
                    return length
                } else {
                    return Int.max
                }
            }
            set {
                objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
                self.addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
            }
        }
    
        func checkMaxLength(textField: UITextField) {
    
            guard !self.isInputMethod(), let prospectiveText = self.text,
                prospectiveText.count > maxLength
                else {
                    return
            }
    
            let selection = selectedTextRange
            let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
            text = prospectiveText.substring(to: maxCharIndex)
            selectedTextRange = selection
        }
    
        //The method is used to cancel the check when use Chinese Pinyin input method.
        //Becuase the alphabet also appears in the textfield when inputting, we should cancel the check.
        func isInputMethod() -> Bool {
            if let positionRange = self.markedTextRange {
                if let _ = self.position(from: positionRange.start, offset: 0) {
                    return true
                }
            }
            return false
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 02:42

    Other answers do not handle the case where user can paste a long string from clipboard. If I paste a long string it should just be truncated but shown. Use this in your delegate:

    static const NSUInteger maxNoOfCharacters = 5;
    
    -(IBAction)textdidChange:(UITextField * )textField
    {
    NSString * text = textField.text;
    
    if(text.length > maxNoOfCharacters)
    {
        text = [text substringWithRange:NSMakeRange(0, maxNoOfCharacters)];
        textField.text = text;
    }
    
    // use 'text'
    
    }
    
    0 讨论(0)
  • 2020-11-22 02:42

    Use this code here RESTRICTED_LENGTH is length you want to restrict for textfield.

       - (BOOL)textField:(UITextField *)textField     shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
        if (textField == nameTF) {
        int limit = RESTRICTED_LENGTH - 1;
        return !([textField.text length]>limit && [string length] > range.length);
        }
       else
       {
        return YES;
       }
    
    return NO;
    
    }
    
    0 讨论(0)
  • 2020-11-22 02:44

    Use below extension to set the maximum character length of a UITextField and UITextView.

    Swift 4.0

        private var kAssociationKeyMaxLength: Int = 0
        private var kAssociationKeyMaxLengthTextView: Int = 0
        extension UITextField {
    
    
            @IBInspectable var maxLength: Int {
                get {
                    if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
                        return length
                    } else {
                        return Int.max
                    }
                }
                set {
                    objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
                    addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
                }
            }
    
            @objc func checkMaxLength(textField: UITextField) {
                guard let prospectiveText = self.text,
                    prospectiveText.count > maxLength
                    else {
                        return
                }
    
                let selection = selectedTextRange
    
                let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
                let substring = prospectiveText[..<indexEndOfText]
                text = String(substring)
    
                selectedTextRange = selection
            }
        }
    

    UITextView

    extension UITextView:UITextViewDelegate {
    
    
            @IBInspectable var maxLength: Int {
                get {
                    if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLengthTextView) as? Int {
                        return length
                    } else {
                        return Int.max
                    }
                }
                set {
                    self.delegate = self
    
                    objc_setAssociatedObject(self, &kAssociationKeyMaxLengthTextView, newValue, .OBJC_ASSOCIATION_RETAIN)
                }
            }
    
            public func textViewDidChange(_ textView: UITextView) {
                checkMaxLength(textField: self)
            }
            @objc func checkMaxLength(textField: UITextView) {
                guard let prospectiveText = self.text,
                    prospectiveText.count > maxLength
                    else {
                        return
                }
    
                let selection = selectedTextRange
    
                let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
                let substring = prospectiveText[..<indexEndOfText]
                text = String(substring)
    
                selectedTextRange = selection
            }
        }
    

    You can set limit below.

    0 讨论(0)
提交回复
热议问题