Max length UITextField

后端 未结 18 1780
一个人的身影
一个人的身影 2020-11-30 17:42

When I\'ve tried How to you set the maximum number of characters that can be entered into a UITextField using swift?, I saw that if I use all 10 characters, I can\'t erase t

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

    If you want to overwrite the last letter:

    let maxLength = 10
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        if range.location > maxLength - 1 {
            textField.text?.removeLast()
        }
    
        return true
    }
    
    0 讨论(0)
  • 2020-11-30 18:22

    I have been using this protocol / extension in one of my apps, and it's a little more readable. I like how it recognizes backspaces and explicitly tells you when a character is a backspace.

    Some things to consider:

    1.Whatever implements this protocol extension needs to specify a character limit. That's typically going to be your ViewController, but you could implement character limit as a computed property and return something else, for example a character limit on one of your models.

    2. You will need to call this method inside of your text field's shouldChangeCharactersInRange delegate method. Otherwise you won't be able to block text entry by returning false, etc.

    3. You will probably want to allow backspace characters through. That's why I added the extra function to detect backspaces. Your shouldChangeCharacters method can check for this and return 'true' early on so you always allow backspaces.

    protocol TextEntryCharacterLimited{
        var characterLimit:Int { get } 
    }
    
    extension TextEntryCharacterLimited{
    
        func charactersInTextField(textField:UITextField, willNotExceedCharacterLimitWithReplacementString string:String, range:NSRange) -> Bool{
    
            let startingLength = textField.text?.characters.count ?? 0
            let lengthToAdd = string.characters.count
            let lengthToReplace = range.length
    
            let newLength = startingLength + lengthToAdd - lengthToReplace
    
            return newLength <= characterLimit
    
        }
    
        func stringIsBackspaceWith(string:String, inRange range:NSRange) -> Bool{
            if range.length == 1 && string.characters.count == 0 { return true }
            return false
        }
    
    }
    

    If any of you are interested, I have a Github repo where I've taken some of this character limit behavior and put into an iOS framework. There's a protocol you can implement to get a Twitter-like character limit display that shows you how far you've gone above the character limit.

    CharacterLimited Framework on Github

    0 讨论(0)
  • 2020-11-30 18:25

    Im using this;

    Limit 3 char

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
            if let txt = textField.text {
                let currentText = txt + string
                if currentText.count > 3 {
                    return false
                }
                return true
            }
            return true
        }
    
    0 讨论(0)
  • 2020-11-30 18:27

    you can extend UITextField and add an @IBInspectable object for handle it:

    SWIFT 5

    import UIKit
    private var __maxLengths = [UITextField: Int]()
    extension UITextField {
        @IBInspectable var maxLength: Int {
            get {
                guard let l = __maxLengths[self] else {
                    return 150 // (global default-limit. or just, Int.max)
                }
                return l
            }
            set {
                __maxLengths[self] = newValue
                addTarget(self, action: #selector(fix), for: .editingChanged)
            }
        }
        @objc func fix(textField: UITextField) {
            if let t = textField.text {
                textField.text = String(t.prefix(maxLength))
            }
        }
    }
    

    and after that define it on attribute inspector

    See Swift 4 original Answer

    0 讨论(0)
  • 2020-11-30 18:28

    With Swift 5 and iOS 12, try the following implementation of textField(_:shouldChangeCharactersIn:replacementString:) method that is part of the UITextFieldDelegate protocol:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let textFieldText = textField.text,
            let rangeOfTextToReplace = Range(range, in: textFieldText) else {
                return false
        }
        let substringToReplace = textFieldText[rangeOfTextToReplace]
        let count = textFieldText.count - substringToReplace.count + string.count
        return count <= 10
    }
    
    • The most important part of this code is the conversion from range (NSRange) to rangeOfTextToReplace (Range<String.Index>). See this video tutorial to understand why this conversion is important.
    • To make this code work properly, you should also set the textField's smartInsertDeleteType value to UITextSmartInsertDeleteType.no. This will prevent the possible insertion of an (unwanted) extra space when performing a paste operation.

    The complete sample code below shows how to implement textField(_:shouldChangeCharactersIn:replacementString:) in a UIViewController:

    import UIKit
    
    class ViewController: UIViewController, UITextFieldDelegate {
    
        @IBOutlet var textField: UITextField! // Link this to a UITextField in Storyboard
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            textField.smartInsertDeleteType = UITextSmartInsertDeleteType.no
            textField.delegate = self
        }
    
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            guard let textFieldText = textField.text,
                let rangeOfTextToReplace = Range(range, in: textFieldText) else {
                    return false
            }
            let substringToReplace = textFieldText[rangeOfTextToReplace]
            let count = textFieldText.count - substringToReplace.count + string.count
            return count <= 10
        }
    
    }
    
    0 讨论(0)
  • 2020-11-30 18:28
    Here is my version of code. Hope it helps!
    
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
            let invalidCharacters = NSCharacterSet(charactersInString: "0123456789").invertedSet
    
            if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex))
            {
                return false
            }
    
            if (count(textField.text) > 10  && range.length == 0)
            {
                self.view.makeToast(message: "Amount entry is limited to ten digits", duration: 0.5, position: HRToastPositionCenter)
                return false
            }
            else
            {
    
            }
    
            return true
        }
    
    0 讨论(0)
提交回复
热议问题