Tetapkan panjang karakter maksimum dari UITextField


Jawaban:


1029

Meskipun UITextFieldkelas tidak memiliki properti panjang maks, relatif mudah untuk mendapatkan fungsionalitas ini dengan mengatur bidang teks delegatedan menerapkan metode delegasi berikut:

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

Cepat

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
}

Sebelum bidang teks berubah, UITextField bertanya kepada delegasi apakah teks yang ditentukan harus diubah. Bidang teks belum berubah pada saat ini, jadi kami mengambil panjang saat ini dan panjang string yang kami sisipkan (baik dengan menempelkan teks yang disalin atau mengetik satu karakter menggunakan keyboard), minus panjang jangkauan. Jika nilai ini terlalu panjang (lebih dari 25 karakter dalam contoh ini), kembali NOuntuk melarang perubahan.

Saat mengetikkan satu karakter di akhir bidang teks, itu range.locationakan menjadi panjang bidang saat ini, dan range.lengthakan menjadi 0 karena kami tidak mengganti / menghapus apa pun. Memasukkan ke tengah bidang teks hanya berarti berbeda range.location, dan menempelkan beberapa karakter hanya berarti stringmemiliki lebih dari satu karakter di dalamnya.

Menghapus karakter tunggal atau memotong banyak karakter ditentukan oleh rangedengan panjang tidak nol, dan string kosong. Penggantian hanyalah penghapusan rentang dengan string yang tidak kosong.

Catatan tentang bug "undo" yang mogok

Seperti disebutkan dalam komentar, ada bug dengan UITextFieldyang dapat menyebabkan crash.

Jika Anda menempel ke bidang, tetapi tempel dicegah oleh implementasi validasi Anda, operasi tempel masih dicatat dalam buffer undo aplikasi. Jika Anda kemudian mengaktifkan undo (dengan mengguncang perangkat dan mengonfirmasi Undo), UITextFieldakan mencoba untuk mengganti string yang dianggapnya disisipkan ke dalam dirinya sendiri dengan string kosong. Ini akan macet karena tidak pernah benar - benar menempelkan string ke dirinya sendiri. Ini akan mencoba mengganti bagian dari string yang tidak ada.

Untungnya Anda dapat melindungi UITextFielddari pembunuhan itu sendiri seperti ini. Anda hanya perlu memastikan bahwa rentang yang diusulkan untuk diganti memang ada dalam string saat ini. Inilah yang dilakukan pemeriksaan kewarasan awal di atas.

Swift 3.0 dengan copy dan paste berfungsi dengan baik.

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
    }

Semoga bermanfaat bagi Anda.


7
Menemukan solusi dengan mengelilingi 2 baris tersebut dengan if (textField == _ssn) {} dan menambahkan return YES; pada akhir metode, yang akan memungkinkan semua UITextFields lainnya menerima teks tanpa batasan apa pun. Bagus!
Kyle Clegg

55
Jawaban yang bagus, tetapi operator ternary tidak berguna; Anda bisa memasukkanreturn newLength <= 25;
jowie

2
Bagaimana jika Anda hanya ingin teks tidak tumpah ke bingkai bidang teks; tidak semua karakter memiliki lebar yang sama, bukan?
Morkrom

2
Benar-benar ada bug yang dibatalkan karena @bcherry menyebutkan - diuji dengan UITextFielddi iPad iOS 8.1. (+1 memberi komentar). Apakah penulis akan menambahkan sesuatu tentang ini karena ini adalah jawaban berperingkat teratas? Saya senang melakukan pengeditan, tetapi milik saya secara teratur tampaknya ditolak! :-)
Benjohn

8
@ ferry Di Swift, tanda centang untuk undo case tampaknya memecah entri emoji. Tidakkah seharusnya penghitungan (textField.text) benar-benar dihitung (textField.text.utf16) untuk mencocokkan dengan objc / uikit pelaporan dalam jangkauan (vs varian Swift tentang jumlah hitungan pada string)?
rcw3

62

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

Sunting: masalah kebocoran memori diperbaiki.

masukkan deskripsi gambar di sini


Ide bagus Frouo! Saya memperluasnya dalam jawaban saya untuk memindahkan pemangkasan maxLength ke ekstensi String sehingga juga dapat digunakan untuk hal-hal seperti instance UITextView, dan untuk menambahkan fungsi kenyamanan untuk memanfaatkan ekstensi String ini dalam ekstensi UITextField.
Scott Gardner

1
Tidakkah variabel global ini membuat kebocoran memori, dengan menahan referensi ke semua tampilan teks (yang mereferensi superview hingga root-)
Ixx

3
@Ixx Saya telah diedit untuk memperbaiki masalah kebocoran memori yang Anda tunjukkan + cepat 3. Terima kasih
frouo

1
cara paling indah untuk mencapainya! Terima kasih
Victor Choy

Adakah yang bisa memberikan saya versi objektifnya
MRizwan33

56

Agustus terima kasih! ( Posting )

Ini adalah kode yang akhirnya berhasil:

#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
Sayangnya, solusi ini gagal menghentikan pengguna menyalin dan menempel ke bidang teks, sehingga memungkinkan mereka untuk memotong batas. Jawaban Sickpea mengatasi situasi ini dengan benar.
Semut

5
Ada apa dengan orang yang memiliki pernyataan if untuk mengembalikan TIDAK atau YA? Coba ini: return! (TextField.text.length> = MAX_LENGTH && range.length == 0);
Matt Parkins

atau inireturn textField.text.length < MAX_LENGTH || range.length != 0;
igrek

22

Untuk melengkapi jawaban Agustus , kemungkinan implementasi fungsi yang diusulkan (lihat delegasi UITextField ).

Saya tidak menguji kode domness , tetapi milik saya tidak macet jika pengguna mencapai batasnya, dan itu kompatibel dengan string baru yang datang menggantikan yang lebih kecil atau sama.

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

Anda tidak dapat melakukan ini secara langsung - UITextFieldtidak memiliki atribut maxLength , tetapi Anda dapat mengatur UITextField'sdelegasi, lalu gunakan:

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

5
Saya setuju, ini adalah cara terbaik ke depan, tapi itu tetap sedikit retas. Kirim laporan bug ke Apple yang ingin Anda lihat properti untuk panjang teks. Saya pasti tertarik dengan ini juga.
avocade

5
@avocade, ini bukan peretasan: ini adalah contoh di mana Anda harus melakukan kode kerangka kerja dasar yang seharusnya dilakukan Apple untuk Anda. Ada BANYAK banyak contoh ini di iOS SDK.
Dan Rosenstark

13

Seringkali Anda memiliki beberapa bidang input dengan panjang yang berbeda.

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

Cara terbaik adalah mengatur pemberitahuan tentang perubahan teks. Di Anda-awakeFromNib metode view controller Anda, Anda akan menginginkan:

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

Kemudian di kelas yang sama tambahkan:

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

Kemudian tautkan outlet myTextFieldke Anda UITextFielddan itu tidak akan membiarkan Anda menambahkan karakter lagi setelah Anda mencapai batas. Pastikan untuk menambahkan ini ke metode dealloc Anda:

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

Meskipun saya melakukan ini untuk menghapus kesalahan> myTextField.text = [myTextField.text substringToIndex: limit];
Luke

11

Saya membuat subclass UITextFieldLimit ini :

  • Beberapa bidang teks didukung
  • Tetapkan batas panjang teks
  • Tempelkan pencegahan
  • Menampilkan label karakter kiri di dalam bidang teks, disembunyikan ketika Anda berhenti mengedit.
  • Goyang animasi ketika tidak ada karakter yang tersisa.

Raih UITextFieldLimit.hdan UITextFieldLimit.mdari repositori GitHub ini:

https://github.com/JonathanGurebo/UITextFieldLimit

dan mulai menguji!

Tandai UITextField yang dibuat storyboard Anda dan tautkan ke subclass saya menggunakan Inspektur Identitas:

Inspektur Identitas

Kemudian Anda dapat menautkannya ke IBOutlet dan menetapkan batasnya (standarnya adalah 10).


File ViewController.h Anda harus berisi: (jika Anda tidak ingin mengubah pengaturan, seperti batasnya)

#import "UITextFieldLimit.h"

/.../

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

File ViewController.m Anda harus @synthesize textFieldLimit.


Tetapkan batas panjang teks dalam file ViewController.m Anda:

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

Semoga kelas membantu Anda. Semoga berhasil!


Untuk kebutuhan kecil dari batasan karakter, saya pikir menambahkan kelas Anda hanya akan berlebihan.
Domness

Upaya masih dihargai.
Reaper

11

Ini harus cukup untuk menyelesaikan masalah (ganti 4 dengan batas yang Anda inginkan). Pastikan untuk menambahkan delegasi di IB.

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

9

Gunakan ekstensi di bawah ini untuk mengatur panjang karakter maksimum a UITextFielddan UITextView.

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

Anda dapat mengatur batas di bawah ini.

masukkan deskripsi gambar di sini


jawaban terbaik sejauh ini ,,, terima kasih banyak solusi hebat ketika ada banyak bidang teks yang membutuhkan panjang yang berbeda
Carlos Norena

Solusi hebat untuk textfield dan batas input karakter textview control. Ini menghemat baris kode dan waktu juga untuk pengembang ... :)
Sandip Patel - SM

Ini berfungsi lebih baik daripada solusi lain yang saya temukan. Misalnya, jika Anda memiliki emoji di bidang teks Anda, ekstensi lain yang saya temukan akan melompat ke akhir baris saat mengedit. Tetapi kode Anda tidak melakukan itu. Terima kasih!
Phontaine Judd

7

Saya mensimulasikan penggantian string aktual yang akan terjadi untuk menghitung panjang string di masa depan:

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

Versi Swift 3 // ***** Ini TIDAK akan bekerja dengan Swift 2.x! ***** //

Pertama buat file Swift baru: TextFieldMaxLength.swift, dan kemudian tambahkan kode di bawah ini:

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

dan kemudian Anda akan melihat di Storyboard bidang baru (Panjang Maks) ketika Anda memilih TextField

jika Anda masih memiliki pertanyaan lain, lihat tautan ini: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields -maksimum-panjang-visual-studio-gaya /


Peringatan, variabel global ini membuat kebocoran memori, dengan memegang referensi ke semua tampilan teks.
frouo

6

Menggunakan pembangun Antarmuka Anda dapat menautkan dan mendapatkan acara untuk "Editing berubah" di salah satu fungsi Anda. Sekarang di sana Anda dapat memeriksa panjangnya

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

Kode berikut ini mirip dengan jawaban sickp tetapi menangani operasi salin-rekat dengan benar. Jika Anda mencoba menempelkan teks yang lebih panjang dari batas, kode berikut akan memotong teks agar sesuai dengan batas alih-alih menolak operasi tempel sepenuhnya.

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

Ada solusi umum untuk mengatur panjang maks dalam Swift. Dengan IBInspectable Anda dapat menambahkan Atribut baru di Inspektur Atribut Xcode.masukkan deskripsi gambar di sini

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
    }

}

Solusi bersih dan sempurna
Eduardo

Memegang UITextField di bidang global akan mempertahankannya dalam memori bahkan setelah UIViewController diberhentikan. Ini adalah kebocoran memori. Jangan gunakan metode ini.
Gunhan

5

Untuk membuatnya bekerja dengan cut & paste string berapa pun, saya akan menyarankan mengubah fungsi menjadi sesuatu seperti:

#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

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

Mengapa guard?
oddRaven

periksa apakah teksnya nihil, jika Anda mau, Anda juga dapat menggunakan if @oddRaven
Shan Ye

3

Swift 2.0 +

Pertama-tama buat kelas untuk proses ini. Mari kita sebut itu StringValidator.swift.

Kemudian tempel saja kode berikut di dalamnya.

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
}

}

Sekarang selamatkan kelas .....

Pemakaian..

Sekarang kebagian kelas viewController.swift Anda dan jadikan outlet textfield Anda sebagai ..

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

Sekarang kebagian metode textChangeCharCharactersInRange dan gunakan seperti berikut ini.

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
    }

}

Jangan lupa untuk mengatur protokol delegasi / metode bidang teks.

Biarkan saya jelaskan tentang ini ... Saya menggunakan proses ekstensi sederhana dari string yang saya tulis di dalam kelas lain. Sekarang saya hanya memanggil metode ekstensi dari kelas lain di mana saya membutuhkannya dengan menambahkan cek dan nilai maksimum.

Fitur...

  1. Ini akan menetapkan batas maksimum bidang teks tertentu.
  2. Ini akan mengatur jenis kunci yang diterima untuk bidang teks tertentu.

Jenis ...

berisiOnlyCharactersIn // Hanya Menerima Karakter.

berisiCharactersIn // Menerima kombinasi karakter

doesNotContainsCharactersIn // Tidak akan menerima karakter

Semoga ini bisa membantu .... Terima kasih ..


3

cepat 3.0

Kode ini berfungsi dengan baik ketika Anda menempelkan string lebih dari batas karakter Anda.

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
    }

Terima kasih untuk suaramu. :)


2
UITextField, bukan UITextView.
Jonny

3

Saya memberikan jawaban tambahan berdasarkan @Frouo. Saya pikir jawabannya adalah cara yang paling indah. Karena itu adalah kontrol umum yang dapat kita gunakan kembali.

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

Ini adalah cara yang benar untuk menangani panjang maks pada UITextField, ini memungkinkan kunci kembali untuk keluar dari pengunduran diri bidang teks sebagai responden pertama dan memungkinkan pengguna mundur ruang ketika mereka mencapai batas

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

Bagaimana dengan pendekatan sederhana ini. Ini bekerja dengan baik untuk saya.

extension UITextField {

    func  charactersLimit(to:Int) {

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

Kemudian:

someTextField.charactersLimit(to:16)

1

Jawaban lain tidak menangani kasus di mana pengguna dapat menempelkan string panjang dari clipboard. Jika saya tempel string yang panjang, itu hanya akan dipotong tetapi ditampilkan. Gunakan ini di delegasi Anda:

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

Dapatkan hingga 1 baris kode :)

Tetapkan delegasi tampilan teks Anda ke "diri" lalu tambahkan kode <UITextViewDelegate>.h dan kode berikut di file .m .... Anda dapat menyesuaikan angka "7" menjadi apa pun yang Anda inginkan dengan jumlah karakter MAKSIMUM Anda.

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

Kode ini menjelaskan pengetikan karakter baru, menghapus karakter, memilih karakter kemudian mengetik atau menghapus, memilih karakter dan memotong, menempel secara umum, dan memilih karakter dan menempel.

Selesai!






Atau, cara keren lain untuk menulis kode ini dengan operasi bit adalah

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

Saya telah membuka sumber subclass UITextField, STATextField , yang menawarkan fungsi ini (dan banyak lagi) dengan maxCharacterLengthpropertinya.


1

sekarang berapa banyak karakter yang Anda inginkan hanya memberikan nilai

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

Gunakan kode ini di sini RESTRICTED_LENGTH adalah panjang yang ingin Anda batasi untuk bidang teks.

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

Saya melakukan ini di Swift untuk batas 8 karakter saat menggunakan tombol angka.

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

Saya harus menguji untuk string! = "" Untuk memungkinkan tombol hapus untuk bekerja pada tombol angka, jika tidak, itu tidak akan memungkinkan menghapus karakter di bidang teks setelah mencapai maksimum.


1

Untuk Xamarin:

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

1

Saya telah menerapkan Ekstensi UITextField untuk menambahkan properti maxLength.

Ini didasarkan pada Xcode 6 IBInspectables, sehingga Anda dapat mengatur batas maxLength pada pembangun Antarmuka.

Berikut implementasinya:

UITextField + MaxLength.h

#import <UIKit/UIKit.h>

@interface UITextField_MaxLength : UITextField<UITextFieldDelegate>

@property (nonatomic)IBInspectable int textMaxLength;
@end

UITextField + MaxLength.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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.