Đặt độ dài ký tự tối đa của UITextField


474

Làm cách nào tôi có thể đặt số lượng ký tự tối đa trong UITextFieldSDK trên iPhone khi tôi tải lên UIView?


câu trả lời cực kỳ cũ này đã hết hạn - câu trả lời bây giờ không quan trọng: stackoverflow.com/a/38306929/294884
Fattie

Câu trả lời:


1029

Mặc dù UITextFieldlớp không có thuộc tính độ dài tối đa, việc lấy chức năng này tương đối đơn giản bằng cách đặt trường văn bản delegatevà thực hiện phương thức ủy nhiệm sau:

Mục tiêu-C

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // Prevent crashing undo bug – see note below.
    if(range.length + range.location > textField.text.length)
    {
        return NO;
    }

    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    return newLength <= 25;
}

Nhanh

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

    let currentCharacterCount = textField.text?.count ?? 0
    if range.length + range.location > currentCharacterCount {
        return false
    }
    let newLength = currentCharacterCount + string.count - range.length
    return newLength <= 25
}

Trước khi trường văn bản thay đổi, UITextField sẽ hỏi đại biểu nếu văn bản được chỉ định sẽ được thay đổi. Trường văn bản không thay đổi tại thời điểm này, vì vậy chúng tôi lấy chiều dài hiện tại và độ dài chuỗi chúng tôi đang chèn (thông qua việc dán văn bản sao chép hoặc nhập một ký tự bằng bàn phím), trừ đi độ dài phạm vi. Nếu giá trị này quá dài (hơn 25 ký tự trong ví dụ này), hãy quay lại NOđể cấm thay đổi.

Khi nhập một ký tự ở cuối trường văn bản, range.locationsẽ là độ dài của trường hiện tại và range.lengthsẽ là 0 vì chúng tôi không thay thế / xóa bất cứ thứ gì. Chèn vào giữa một trường văn bản chỉ có nghĩa là khác nhau range.locationvà dán nhiều ký tự chỉ có nghĩa là stringcó nhiều hơn một ký tự trong đó.

Xóa các ký tự đơn hoặc cắt nhiều ký tự được chỉ định bởi a rangecó độ dài khác không và một chuỗi trống. Thay thế chỉ là một phạm vi xóa với một chuỗi không trống.

Một lưu ý về lỗi "hoàn tác" bị lỗi

Như đã đề cập trong các ý kiến, có một lỗi với UITextFieldnó có thể dẫn đến một sự cố.

Nếu bạn dán vào trường, nhưng việc dán bị ngăn cản bởi quá trình xác thực của bạn, thao tác dán vẫn được ghi lại trong bộ đệm hoàn tác của ứng dụng. Nếu sau đó bạn thực hiện hoàn tác (bằng cách lắc thiết bị và xác nhận Hoàn tác), thì UITextFieldsẽ cố gắng thay thế chuỗi mà nó nghĩ rằng nó đã dán vào chính nó bằng một chuỗi trống. Điều này sẽ sụp đổ bởi vì nó không bao giờ thực sự dán chuỗi vào chính nó. Nó sẽ cố gắng thay thế một phần của chuỗi không tồn tại.

May mắn thay, bạn có thể bảo vệ UITextFieldkhỏi tự sát như thế này. Bạn chỉ cần để đảm bảo rằng phạm vi nó đề xuất để thay thế không tồn tại trong chuỗi hiện tại của nó. Đây là những gì kiểm tra vệ sinh ban đầu ở trên làm.

swift 3.0 với bản sao và dán hoạt động tốt.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let str = (textView.text + text)
        if str.characters.count <= 10 {
            return true
        }
        textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
        return false
    }

Hy vọng nó hữu ích cho bạn.


7
Tìm thấy giải pháp bằng cách bao quanh 2 dòng đó với if (textField == _ssn) {} và thêm return return; ở cuối phương thức, điều này sẽ cho phép tất cả các UITextField khác chấp nhận văn bản mà không có bất kỳ hạn chế nào. Tiện lợi!
Kyle Clegg

55
Câu trả lời tốt, nhưng toán tử ternary là thừa; bạn chỉ có thể đặtreturn newLength <= 25;
jowie

2
Điều gì sẽ xảy ra nếu bạn chỉ muốn văn bản không tràn qua khung của trường văn bản; Không phải tất cả các ký tự đều có cùng chiều rộng, phải không?
Morkrom

2
Thực sự có một lỗi hoàn tác như @bcherry đề cập - đã được thử nghiệm UITextFieldtrên iPad iOS 8.1. (+1 để bình luận). Tác giả sẽ thêm một cái gì đó về điều này vì nó là câu trả lời được xếp hạng hàng đầu? Tôi rất vui khi thực hiện chỉnh sửa, nhưng tôi thường xuyên bị từ chối! :-)
Stewohn

8
@bherry Trong Swift, việc kiểm tra trường hợp hoàn tác dường như phá vỡ mục nhập của biểu tượng cảm xúc. Không nên đếm (textField.text) trên thực tế (textField.text.utf16) để khớp với báo cáo objc / uikit trong phạm vi (so với biến thể đếm trên chuỗi của Swift)?
RCw3

62

Swift 4

import UIKit

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

Chỉnh sửa: vấn đề rò rỉ bộ nhớ đã được sửa.

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


Ý tưởng tuyệt vời Frouo! Tôi đã mở rộng theo câu trả lời của mình để chuyển phần cắt tối đa sang phần mở rộng Chuỗi để nó cũng có thể được sử dụng cho những thứ như phiên bản UITextView và để thêm chức năng tiện lợi để tận dụng các tiện ích mở rộng Chuỗi này trong tiện ích mở rộng UITextField.
Scott Gardner

1
Không phải biến toàn cục này tạo ra rò rỉ bộ nhớ, bằng cách giữ các tham chiếu đến tất cả các lần xem văn bản (tham chiếu các giám sát cho đến khi root-)
Ixx

3
@Ixx Tôi đã chỉnh sửa để khắc phục sự cố rò rỉ bộ nhớ mà bạn đã chỉ ra + swift 3. Cảm ơn
frouo

1
cách đẹp nhất để đạt được nó! Cảm ơn
Victor Choy

bất cứ ai có thể cung cấp cho tôi phiên bản mục tiêu của nó
MRizwan33

56

Cảm ơn bạn tháng tám! ( Bài )

Đây là mã mà tôi đã kết thúc với nó hoạt động:

#define MAX_LENGTH 20

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField.text.length >= MAX_LENGTH && range.length == 0)
    {
        return NO; // return NO to not change text
    }
    else
    {return YES;}
}

19
Thật không may, giải pháp này không thể ngăn người dùng sao chép và dán vào trường văn bản, do đó cho phép họ vượt qua giới hạn. Câu trả lời của Sickpea đối phó với tình huống này một cách chính xác.
Kiến

5
Điều gì xảy ra với những người có câu lệnh if trả về KHÔNG hoặc CÓ? Hãy thử điều này: return! (TextField.text.length> = MAX_LENGTH && Range.length == 0);
Matt Parkins

hoặc nàyreturn textField.text.length < MAX_LENGTH || range.length != 0;
igrek

22

Để hoàn thành câu trả lời tháng 8 , có thể thực hiện chức năng được đề xuất (xem đại biểu của UITextField ).

Tôi đã không kiểm tra domness mã, nhưng tôi không gặp khó khăn nếu người dùng đạt đến giới hạn, và nó tương thích với một chuỗi mới mà đến thay thế một nhỏ hơn hoặc bằng.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //limit the size :
    int limit = 20;
    return !([textField.text length]>limit && [string length] > range.length);
}

17

Bạn không thể làm điều này trực tiếp - UITextFieldkhông có thuộc tính maxLạng , nhưng bạn có thể đặt UITextField'sđại biểu, sau đó sử dụng:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

5
Tôi đồng ý, đây là cách tốt nhất về phía trước, nhưng nó vẫn là một chút hack. Gửi báo cáo lỗi cho Apple rằng bạn muốn xem một thuộc tính cho độ dài văn bản. Tôi chắc chắn cũng quan tâm đến điều này.
avocade

5
@avocade, đó không phải là hack: đó là một ví dụ mà bạn phải thực hiện mã khung cơ bản mà Apple nên làm cho bạn. Có NHIỀU ví dụ về điều này trong SDK iOS.
Dan Rosenstark

13

Thường thì bạn có nhiều trường đầu vào với độ dài khác nhau.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    int allowedLength;
    switch(textField.tag) {
        case 1: 
            allowedLength = MAXLENGTHNAME;      // triggered for input fields with tag = 1
            break;
        case 2:
            allowedLength = MAXLENGTHADDRESS;   // triggered for input fields with tag = 2
            break;
        default:
            allowedLength = MAXLENGTHDEFAULT;   // length default when no tag (=0) value =255
            break;
    }

    if (textField.text.length >= allowedLength && range.length == 0) {
        return NO; // Change not allowed
    } else {
        return YES; // Change allowed
    }
}

12

Cách tốt nhất sẽ là thiết lập một thông báo về việc thay đổi văn bản. Trong -awakeFromNibphương pháp điều khiển xem của bạn, bạn sẽ muốn:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextField:) name:@"UITextFieldTextDidChangeNotification" object:myTextField];

Sau đó, trong cùng một lớp thêm:

- (void)limitTextField:(NSNotification *)note {
    int limit = 20;
    if ([[myTextField stringValue] length] > limit) {
        [myTextField setStringValue:[[myTextField stringValue] substringToIndex:limit]];
    }
}

Sau đó liên kết ổ cắm myTextFieldvới bạn UITextFieldvà nó sẽ không cho phép bạn thêm bất kỳ ký tự nào sau khi bạn đạt đến giới hạn. Hãy chắc chắn để thêm điều này vào phương thức dealloc của bạn:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];

Mặc dù tôi đã làm điều này để xóa lỗi> myTextField.text = [myTextField.text sub chuỗiTo Index: giới hạn];
Lu-ca

11

Tôi đã tạo lớp con UITextFieldLimit này :

  • Hỗ trợ nhiều trường văn bản
  • Đặt giới hạn độ dài văn bản
  • Phòng chống dán
  • Hiển thị nhãn của các ký tự bên trái trong trường văn bản, bị ẩn khi bạn dừng chỉnh sửa.
  • Lắc hoạt hình khi không còn ký tự.

Lấy UITextFieldLimit.hUITextFieldLimit.mtừ kho lưu trữ GitHub này:

https://github.com/JonathanGurebo/UITextFieldLimit

và bắt đầu thử nghiệm!

Đánh dấu UITextField do bảng phân cảnh của bạn tạo và liên kết nó với lớp con của tôi bằng Trình kiểm tra danh tính:

Thanh tra danh tính

Sau đó, bạn có thể liên kết nó với IBOutlet và đặt giới hạn (mặc định là 10).


Tệp ViewControll.h của bạn phải chứa: (nếu bạn không sửa đổi cài đặt, như giới hạn)

#import "UITextFieldLimit.h"

/.../

@property (weak, nonatomic) IBOutlet UITextFieldLimit *textFieldLimit; // <--Your IBOutlet

Tập tin ViewControll.m của bạn nên @synthesize textFieldLimit.


Đặt giới hạn độ dài văn bản trong tệp ViewControll.m của bạn:

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

    [textFieldLimit setLimit:25];// <-- and you won't be able to put more than 25 characters in the TextField.
}

Hy vọng lớp học giúp bạn. Chúc may mắn!


Đối với nhu cầu nhỏ về giới hạn ký tự, tôi nghĩ việc thêm lớp của bạn sẽ chỉ là quá mức cần thiết.
Domness

Vẫn nỗ lực đánh giá cao.
Reaper

11

Điều này là đủ để giải quyết vấn đề (thay thế 4 bằng giới hạn bạn muốn). Chỉ cần đảm bảo thêm đại biểu trong IB.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
     NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
     return (newString.length<=4);
}

9

Sử dụng phần mở rộng bên dưới để đặt độ dài ký tự tối đa của a UITextFieldUITextView.

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

Xem UIText

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

Bạn có thể đặt giới hạn dưới đây.

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


Câu trả lời hay nhất cho đến nay ,, cảm ơn rất nhiều giải pháp tuyệt vời khi có nhiều trường văn bản cần độ dài khác nhau
Carlos Norena

Giải pháp thực sự tuyệt vời cho giới hạn nhập ký tự điều khiển textfield và textview. Nó tiết kiệm dòng mã và thời gian cho nhà phát triển ... :)
Sandip Patel - SM

Điều này hoạt động tốt hơn so với các giải pháp khác tôi tìm thấy. Chẳng hạn, nếu bạn có biểu tượng cảm xúc trong trường văn bản của mình, các tiện ích mở rộng khác mà tôi tìm thấy sẽ bỏ qua đến cuối dòng khi chỉnh sửa. Nhưng mã của bạn không làm điều đó. Cảm ơn!
Phontaine Judd

7

Tôi mô phỏng sự thay thế chuỗi thực tế sắp xảy ra để tính toán độ dài của chuỗi tương lai đó:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];

    if([newString length] > maxLength)
       return NO;

    return YES;
}

7

Phiên bản Swift 3 // ***** Điều này sẽ KHÔNG hoạt động với Swift 2.x! ***** //

Đầu tiên tạo một tệp Swift mới: TextFieldMaxL wavel.swift, sau đó thêm mã dưới đây:

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),
         for: UIControlEvents.editingChanged
      )
   }
}
func limitLength(textField: UITextField) {
    guard let prospectiveText = textField.text,
        prospectiveText.characters.count > maxLength
    else {
        return
    }

   let selection = selectedTextRange
   let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
   text = prospectiveText.substring(to: maxCharIndex)
   selectedTextRange = selection
   }
}

và sau đó bạn sẽ thấy trong Storyboard một trường mới (Độ dài tối đa) khi bạn chọn bất kỳ TextField nào

nếu bạn vẫn còn nhiều câu hỏi, hãy xem liên kết này: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields -maximum-length-visual-studio-style /


Cảnh báo, biến toàn cục này tạo ra rò rỉ bộ nhớ, bằng cách giữ các tham chiếu đến tất cả các bài xem.
frouo

6

Sử dụng Trình xây dựng giao diện, bạn có thể liên kết và nhận sự kiện cho "Chỉnh sửa đã thay đổi" trong bất kỳ chức năng nào của bạn. Bây giờ bạn có thể đặt kiểm tra độ dài

- (IBAction)onValueChange:(id)sender 
{
    NSString *text = nil;
    int MAX_LENGTH = 20;
    switch ([sender tag] ) 
    {
        case 1: 
        {
            text = myEditField.text;
            if (MAX_LENGTH < [text length]) {
                myEditField.text = [text substringToIndex:MAX_LENGTH];
            }
        }
            break;
        default:
            break;
    }

}

6

Đoạn mã sau tương tự như câu trả lời của bệnh nhân nhưng xử lý các thao tác sao chép-dán chính xác. Nếu bạn cố gắng dán một văn bản dài hơn giới hạn, đoạn mã sau sẽ cắt bớt văn bản để phù hợp với giới hạn thay vì từ chối hoàn toàn thao tác dán.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    static const NSUInteger limit = 70; // we limit to 70 characters
    NSUInteger allowedLength = limit - [textField.text length] + range.length;
    if (string.length > allowedLength) {
        if (string.length > 1) {
            // get at least the part of the new string that fits
            NSString *limitedString = [string substringToIndex:allowedLength];
            NSMutableString *newString = [textField.text mutableCopy];
            [newString replaceCharactersInRange:range withString:limitedString];
            textField.text = newString;
        }
        return NO;
    } else {
        return YES;
    }
}

6

giải pháp chung để thiết lập độ dài tối đa trong Swift. Bằng IBInspectable, bạn có thể thêm Thuộc tính mới trong Trình kiểm tra thuộc tính Xcode.nhập mô tả hình ảnh ở đây

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
    }

}

Giải pháp sạch sẽ và hoàn hảo
Eduardo

Giữ một UITextField trong trường toàn cầu sẽ giữ chúng trong bộ nhớ ngay cả sau khi UIViewControll bị loại bỏ. Đây là một rò rỉ bộ nhớ. Đừng sử dụng phương pháp này.
Gunhan

5

Để làm cho nó hoạt động với việc cắt và dán các chuỗi có độ dài bất kỳ, tôi khuyên bạn nên thay đổi chức năng thành một cái gì đó như:

#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;
        }
    }

4

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
}

Tại sao guard?
lẻRaven

kiểm tra xem văn bản có phải không, nếu bạn muốn, bạn cũng có thể sử dụng nếu @oddRaven
Shan Ye

3

Swift 2.0 +

Trước hết tạo một lớp cho quá trình này. Hãy gọi nó là StringValidator.swift.

Sau đó chỉ cần dán đoạn mã sau vào bên trong nó.

import Foundation

extension String {

func containsCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) != nil
}

func containsOnlyCharactersIn(matchCharacters: String) -> Bool {
let disallowedCharacterSet = NSCharacterSet(charactersInString: matchCharacters).invertedSet
return self.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
}


func doesNotContainCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) == nil
}

func isNumeric() -> Bool
{
let scanner = NSScanner(string: self)
scanner.locale = NSLocale.currentLocale()

return scanner.scanDecimal(nil) && scanner.atEnd
}

}

Bây giờ lưu lớp .....

Sử dụng..

Bây giờ, hãy xem lớp viewControll.swift của bạn và đặt các cửa hàng của trường văn bản của bạn là ..

@IBOutlet weak var contactEntryTxtFld: UITextField! //First textfield
@IBOutlet weak var contactEntryTxtFld2: UITextField!   //Second textfield

Bây giờ, hãy chọn phương thức ShouldChangeChar characterInRange của textfield và sử dụng như sau.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if string.characters.count == 0 {
        return true
    }
    let latestText = textField.text ?? ""
    let checkAbleText = (latestText as NSString).stringByReplacingCharactersInRange(range, withString: string)


    switch textField {

    case contactEntryTxtFld:
        return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5

    case contactEntryTxtFld2:
        return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5

    default:
        return true
    }

}

Đừng quên thiết lập giao thức / phương thức của trường văn bản.

Hãy để tôi giải thích về điều này ... Tôi đang sử dụng quy trình mở rộng đơn giản của chuỗi mà tôi đã viết bên trong một lớp khác. Bây giờ tôi chỉ gọi các phương thức mở rộng đó từ một lớp khác mà tôi cần chúng bằng cách thêm kiểm tra và giá trị tối đa.

Đặc trưng...

  1. Nó sẽ đặt giới hạn tối đa của một trường văn bản cụ thể.
  2. Nó sẽ đặt loại khóa được chấp nhận cho trường văn bản cụ thể.

Các loại ...

chứaOnlyChar characterIn // Chỉ chấp nhận các ký tự.

chứaChar characterIn // Chấp nhận kết hợp các ký tự

doesNotContainsChar characterIn // Sẽ không chấp nhận các ký tự

Hy vọng điều này đã giúp .... Cảm ơn ..


3

nhanh chóng 3.0

Mã này hoạt động tốt khi bạn dán chuỗi nhiều hơn giới hạn ký tự của bạn.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let str = (textView.text + text)
        if str.characters.count <= 10 {
            return true
        }
        textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
        return false
    }

Cảm ơn bạn đã bình chọn. :)


2
UITextField, không phải UITextView.
Jonny

3

Tôi đưa ra một câu trả lời bổ sung dựa trên @Frouo. Tôi nghĩ rằng câu trả lời của anh ấy là cách đẹp nhất. Vì nó là một điều khiển chung mà chúng ta có thể sử dụng lại.

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
    }

}

2

Đây là cách chính xác để xử lý độ dài tối đa trên UITextField, nó cho phép phím quay lại thoát khỏi trường văn bản dưới dạng phản hồi đầu tiên và cho phép người dùng lùi lại khi đạt đến giới hạn

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int MAX_LENGHT = 5;
    if([string isEqualToString:@"\n"])
    {
        [textField resignFirstResponder];
        return FALSE;
    }
    else if(textField.text.length > MAX_LENGHT-1)
    {
        if([string isEqualToString:@""] && range.length == 1)
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    else
    {
        return TRUE;
    }
}

2

Điều gì về phương pháp đơn giản này. Nó làm việc tốt cho tôi.

extension UITextField {

    func  charactersLimit(to:Int) {

        if (self.text!.count > to) {
            self.deleteBackward()
        }
    }
}

Sau đó:

someTextField.charactersLimit(to:16)

1

Các câu trả lời khác không xử lý trường hợp người dùng có thể dán một chuỗi dài từ clipboard. Nếu tôi dán một chuỗi dài, nó sẽ bị cắt ngắn nhưng được hiển thị. Sử dụng điều này trong đại biểu của bạn:

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'

}

1

Có nó xuống 1 dòng mã :)

Đặt đại biểu xem văn bản của bạn để "tự" sau đó thêm <UITextViewDelegate>trong .h của bạn và đoạn mã sau vào .m của bạn .... bạn có thể điều chỉnh số "7" là bất cứ điều gì bạn muốn số lượng tối đa của bạn của nhân vật được.

-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
    return ((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length)>0);
}

Mã này chiếm tài khoản để gõ các ký tự mới, xóa các ký tự, chọn các ký tự sau đó nhập hoặc xóa, chọn các ký tự và cắt, dán nói chung, và chọn các ký tự và dán.

Làm xong!






Ngoài ra, một cách thú vị khác để viết mã này với các thao tác bit sẽ là

-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
    return 0^((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length));
}

1

Tôi đã mở một lớp con UITextField, STATextField , cung cấp chức năng này (và nhiều hơn nữa) với thuộc tính của nó maxCharacterLength.


1

Bây giờ có bao nhiêu ký tự bạn muốn chỉ đưa ra giá trị

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range   replacementString:(NSString *)string {
     NSUInteger newLength = [textField.text length] + [string length] - range.length;
     return (newLength > 25) ? NO : YES;
  }

1

Sử dụng mã này tại đây RESTRICTED_LENGTH là độ dài bạn muốn hạn chế cho trường văn bản.

   - (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;

}

1

Tôi đã làm điều này trong Swift với giới hạn 8 ký tự khi sử dụng bàn phím số.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    return !(textField.text?.characters.count == MAX_LENGTH && string != "")
}

Tôi đã phải kiểm tra chuỗi! = "" Để cho phép nút xóa hoạt động trên bàn phím số, nếu không, nó sẽ không cho phép xóa các ký tự trong trường văn bản sau khi đạt đến mức tối đa.


1

Đối với Xamarin:

YourTextField.ShouldChangeCharacters = 
delegate(UITextField textField, NSRange range, string replacementString)
        {
            return (range.Location + replacementString.Length) <= 4; // MaxLength == 4
        };

1

Tôi đã thực hiện một mở rộng UITextField để thêm một tài sản maxLength với nó.

Nó dựa trên Xcode 6 IBInspectables, vì vậy bạn có thể đặt giới hạn tối đa cho trình tạo Giao diện.

Đây là cách thực hiện:

UITextField + MaxLạng.h

#import <UIKit/UIKit.h>

@interface UITextField_MaxLength : UITextField<UITextFieldDelegate>

@property (nonatomic)IBInspectable int textMaxLength;
@end

UITextField + MaxLpm.m

#import "UITextField+MaxLength.h"

@interface UITextField_MaxLength()

@property (nonatomic, assign) id <UITextFieldDelegate> superDelegate;

@end

@implementation UITextField_MaxLength

- (BOOL)textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    //validate the length, only if it's set to a non zero value
    if (self.textMaxLength>0) {
        if(range.length + range.location > textField.text.length)
            return NO;

        if (textField.text.length+string.length - range.length>self.textMaxLength) {
            return NO;
        }
    }

    //if length validation was passed, query the super class to see if the delegate method is implemented there
    if (self.superDelegate && [self.superDelegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
        return [self.superDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string];
    }
    else{
        //if the super class does not implement the delegate method, simply return YES as the length validation was passed
        return YES;
    }
}

- (void)setDelegate:(id<UITextFieldDelegate>)delegate {
    if (delegate == self)
        return;
    self.superDelegate = delegate;
    [super setDelegate:self];
}

//forward all non overriden delegate methods
- (id)forwardingTargetForSelector:(SEL)aSelector {
    if ([self.superDelegate  respondsToSelector:aSelector])
        return self.superDelegate;

    return [super forwardingTargetForSelector:aSelector];
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    if ([self.superDelegate respondsToSelector:aSelector])
        return YES;

    return [super respondsToSelector:aSelector];
}
@end
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.