Độ dài tối đa UITextField


120

Khi tôi đã thử Làm thế nào để bạn đặt số ký tự tối đa có thể được nhập vào UITextField bằng cách sử dụng nhanh? , Mình thấy nếu dùng cả 10 ký tự thì cũng không xóa được ký tự.

Điều duy nhất tôi có thể làm là hủy hoạt động (xóa tất cả các ký tự cùng nhau).

Có ai biết làm thế nào để không chặn bàn phím (để tôi không thể thêm các chữ cái / ký hiệu / số khác, nhưng tôi có thể sử dụng phím xóa lùi)?

Câu trả lời:


295

Với Swift 5 và iOS 12, hãy thử triển khai textField(_:shouldChangeCharactersIn:replacementString:)phương pháp sau đây là một phần của UITextFieldDelegategiao thức:

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
}
  • Phần quan trọng nhất của mã này là chuyển đổi từ range( NSRange) sang rangeOfTextToReplace( Range<String.Index>). Xem hướng dẫn bằng video này để hiểu tại sao chuyển đổi này lại quan trọng.
  • Để làm cho mã này hoạt động bình thường, bạn cũng nên đặt giá trị textFieldcủa 's smartInsertDeleteTypethành UITextSmartInsertDeleteType.no. Điều này sẽ ngăn chặn việc có thể chèn thêm một khoảng trống (không mong muốn) khi thực hiện thao tác dán.

Mẫu mã hoàn chỉnh dưới đây cho thấy làm thế nào để thực hiện textField(_:shouldChangeCharactersIn:replacementString:)trong một 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
    }

}

Bạn chỉ cần đặt mã này vào lớp bộ điều khiển chế độ xem của mình? Hay tôi phải kết nối?
Isaac Wasserman

Nếu ai đó cần đưa ra một số điều kiện..bạn có thể làm như thế này ... if (textField .isEqual (mobileNumberTextfield)) {Guard let text = textField.text else {return true} let newLength = text.characters.count + string.characters.count - range.length return newLength <= limitLength; } trả về true;
Narasimha Nallamsetty

6
Đối với Swift 4, text.characters.countlà sử dụng NỮAtext.count
Mohamed Salah

47

Tôi làm như thế này:

func checkMaxLength(textField: UITextField!, maxLength: Int) {
    if (countElements(textField.text!) > maxLength) {
        textField.deleteBackward()
    }
}

Mã làm việc cho tôi. Nhưng tôi làm việc với bảng phân cảnh. Trong Storyboard, tôi thêm một hành động cho trường văn bản trong bộ điều khiển chế độ xem khi chỉnh sửa đã thay đổi .


1
countElements đã được thay đổi thành count trong Swift 2, nhưng việc thay đổi đó phù hợp với tôi!
John

1
Cảm ơn, bạn có thể sử dụng textField.text? .Characters.count ngay bây giờ vì countElements đã được thay đổi.
Anibal R.

1
Tks, nó hoạt động tuyệt vời với thay đổi này: countElements (textField.text!) Trong Swift 2 là: textField.text? .Characters.count
kha

33

Cập nhật cho Swift 4

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
     guard let text = textField.text else { return true }
     let newLength = text.count + string.count - range.length
     return newLength <= 10
}

15

Thêm chi tiết từ câu trả lời @Martin

// linked your button here
@IBAction func mobileTFChanged(sender: AnyObject) {
    checkMaxLength(sender as! UITextField, maxLength: 10)
}

// linked your button here
@IBAction func citizenTFChanged(sender: AnyObject) {
    checkMaxLength(sender as! UITextField, maxLength: 13)
}

func checkMaxLength(textField: UITextField!, maxLength: Int) {
    // swift 1.0
    //if (count(textField.text!) > maxLength) {
    //    textField.deleteBackward()
    //}
    // swift 2.0
    if (textField.text!.characters.count > maxLength) {
        textField.deleteBackward()
    }
}

1
count (textField.text!) báo lỗi. Bạn phải sử dụng textField.text .characters.count!
Regis St-Gelais

1
Cảm ơn @ RegisSt-Gelais, Nó đã là một câu trả lời cũ, tôi cập nhật nó bây giờ
Sruit A.Suk

11

Trong Swift 4

Giới hạn 10 ký tự cho trường văn bản và cho phép xóa (xóa lùi)

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField ==  userNameFTF{
            let char = string.cString(using: String.Encoding.utf8)
            let isBackSpace = strcmp(char, "\\b")
            if isBackSpace == -92 {
                return true
            }
            return textField.text!.count <= 9
        }
        return true
    }

8
func checkMaxLength(textField: UITextField!, maxLength: Int) {
        if (textField.text!.characters.count > maxLength) {
            textField.deleteBackward()
        }
}

một thay đổi nhỏ cho IOS 9


8

Swift 3

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

            let nsString = NSString(string: textField.text!)
            let newText = nsString.replacingCharacters(in: range, with: string)
            return  newText.characters.count <= limitCount
    }

8

bạn có thể mở rộng UITextField và thêm một @IBInspectableđối tượng để xử lý nó:

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

và sau đó xác định nó trên trình kiểm tra thuộc tính

nhập mô tả hình ảnh ở đây

Xem câu trả lời gốc của Swift 4


2
Đẹp, mã sạch sẽ. Nhưng vì một số lý do, điều này gây ra hành vi chỉnh sửa kỳ lạ khi bạn sử dụng biểu tượng cảm xúc. Con trỏ lướt đến cuối dòng mỗi khi bạn cố gắng chỉnh sửa.
Phontaine Judd

5

Nếu bạn muốn ghi đè lên chữ cái cuối cùng:

let maxLength = 10

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if range.location > maxLength - 1 {
        textField.text?.removeLast()
    }

    return true
}

4

Tôi đã đăng một giải pháp bằng cách sử dụng IBInspectable, vì vậy bạn có thể thay đổi giá trị độ dài tối đa cả trong trình tạo giao diện hoặc theo chương trình. Kiểm tra nó ở đây


3

Bạn có thể sử dụng trong swift 5 hoặc swift 4 như hình ảnh giống như dưới đây nhập mô tả hình ảnh ở đây

  1. Thêm textField trong View Controller
  2. Kết nối với văn bản tới ViewController
  3. thêm mã trong chế độ xem ViewController

     class ViewController: UIViewController , UITextFieldDelegate {
    
      @IBOutlet weak var txtName: UITextField!
    
      var maxLen:Int = 8;
    
     override func viewDidLoad() {
        super.viewDidLoad()
    
        txtName.delegate = self
       }
    
     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
         if(textField == txtName){
            let currentText = textField.text! + string
            return currentText.count <= maxLen
         }
    
         return true;
       }
    }

Bạn có thể tải xuống biểu mẫu Nguồn đầy đủ GitHub: https://github.com/enamul95/TextFieldMaxLen


1

Hãy cẩn thận với lỗi hoàn tác cho UITextField được đề cập trong bài đăng này: Đặt độ dài ký tự tối đa của UITextField

đây là cách bạn sửa nó nhanh chóng

if(range.length + range.location > count(textField.text)) {
        return false;
}

Nếu bạn muốn hỗ trợ biểu tượng cảm xúc và cách sử dụng như vậy: if (range.length + range.location> count (textField.text.utf16)) {return false; }
AlexD

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

1
Tôi giống như phần mở rộng Toast UIView :)
Regis St-Gelais

1

Tôi đã sử dụng giao thức / tiện ích mở rộng này trong một trong các ứng dụng của mình và nó dễ đọc hơn một chút. Tôi thích cách nó nhận ra các khoảng trống và cho bạn biết một cách rõ ràng khi một ký tự là một dấu lùi.

Một số điều cần xem xét:

1. Bất cứ thứ gì triển khai phần mở rộng giao thức này đều cần chỉ định giới hạn ký tự. Đó thường sẽ là ViewController của bạn, nhưng bạn có thể triển khai giới hạn ký tự như một thuộc tính được tính toán và trả về một cái gì đó khác, ví dụ: giới hạn ký tự trên một trong các mô hình của bạn.

2. Bạn sẽ cần gọi phương thức này bên trong phương thức ủy nhiệm shouldChangeCharactersInRange của trường văn bản. Nếu không, bạn sẽ không thể chặn mục nhập văn bản bằng cách trả về false, v.v.

3. Bạn có thể sẽ muốn cho phép các ký tự xóa lùi thông qua. Đó là lý do tại sao tôi đã thêm chức năng bổ sung để phát hiện khoảng cách ngược. Phương thức shouldChangeCharacters của bạn có thể kiểm tra điều này và trả về 'true' ngay từ sớm để bạn luôn cho phép các khoảng cách ngược.

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
    }

}

Nếu bất kỳ ai trong số các bạn quan tâm, tôi có một repo Github, nơi tôi đã thực hiện một số hành vi giới hạn ký tự này và đưa vào một khuôn khổ iOS. Có một giao thức bạn có thể triển khai để hiển thị giới hạn ký tự giống như Twitter cho bạn biết bạn đã vượt quá giới hạn ký tự bao xa.

CharacterLimited Framework trên Github


1

Vì các đại biểu là mối quan hệ 1-1 và tôi có thể muốn sử dụng nó ở nơi khác vì các lý do khác, tôi muốn hạn chế độ dài trường văn bản bằng cách thêm mã này trong thiết lập của họ:

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        setup()
    }

    required override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    func setup() {

        // your setup...

        setMaxLength()
    }

    let maxLength = 10

    private func setMaxLength() {
            addTarget(self, action: #selector(textfieldChanged(_:)), for: UIControlEvents.editingChanged)
        }

        @objc private func textfieldChanged(_ textField: UITextField) {
            guard let text = text else { return }
            let trimmed = text.characters.prefix(maxLength)
            self.text = String(trimmed)

        }

0

Tôi đang sử dụng cái này;

Giới hạn 3 ký tự

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

Swift 5

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let MAX_LENGTH = 4
        let updatedString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        return updatedString.count <= MAX_LENGTH
    }

-3

Bạn cần kiểm tra xem chuỗi hiện có cộng với đầu vào có lớn hơn 10 hay không.

   func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange,    replacementString string: String!) -> Bool {
      NSUInteger newLength = textField.text.length + string.length - range.length;
      return !(newLength > 10)
   }

5
Mã của bạn sai. 1. Bạn phải khai báo hằng số hoặc biến của mình bằng let hoặc var trong Swift (không phải NSUInteger). 2. textField.text và chuỗi có kiểu String. Chiều dài không phải là thuộc tính / phương thức của Chuỗi trong Swift.
Imanou Petit
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.