Bir UITextField öğesinin maksimum karakter uzunluğunu ayarlama


Yanıtlar:


1029

UITextFieldSınıfta max length özelliği bulunmamakla birlikte, metin alanlarını ayarlayıp delegateaşağıdaki delege yöntemini uygulayarak bu işlevselliği elde etmek nispeten basittir :

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

hızlı

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
}

Metin alanı değiştirir önce belirtilen metin halinde UITextField temsilci sorar gerektiğini değiştirilebilir. Metin alanı bu noktada değişmedi, bu nedenle geçerli uzunluğunu ve eklediğimiz dize uzunluğunu (kopyalanan metni yapıştırarak veya klavyeyi kullanarak tek bir karakter yazarak) ekliyoruz, aralık uzunluğu eksi. Bu değer çok uzunsa (bu örnekte 25 karakterden fazla), NOdeğişikliği yasaklamak için geri dönün .

Bir metin alanının sonuna tek bir karakter yazarken range.location, geçerli alanın uzunluğu range.lengtholacaktır ve hiçbir şey değiştirmediğimiz / silmediğimiz için 0 olacaktır. Bir metin alanının ortasına yerleştirmek sadece farklı anlamına gelir range.locationve birden çok karakteri yapıştırmak içinde birden fazla karakter olması anlamına gelir string.

Tek karakterleri silmek veya birden çok karakteri kesmek, rangeuzunluğu sıfır olmayan bir karakter ve boş bir dize ile belirtilir. Değiştirme, boş olmayan bir dizeyle yalnızca aralık silme işlemidir.

Kilitlenen "geri al" hatasıyla ilgili bir not

Yorumlarda belirtildiği gibi, çökmeye UITextFieldyol açabilecek bir hata var .

Alana yapıştırırsanız ancak doğrulama uygulamanız tarafından yapıştırma engellenirse, yapıştırma işlemi yine de uygulamanın geri alma arabelleğine kaydedilir. Daha sonra bir geri UITextFieldalmayı başlatırsanız (cihazı sallayarak ve bir Geri Al onaylayarak), kendisine yapıştırdığı düşünülen dizeyi boş bir dize ile değiştirmeye çalışır. Asla, çünkü bu kilitlenmesine aslında kendisine dizeyi yapıştırılan. Dizenin var olmayan bir kısmını değiştirmeye çalışır.

Neyse ki UITextFieldkendini böyle öldürmekten koruyabilirsiniz . Sadece daha değiştirmek için teklif aralığı sağlamak için gereken does bugünkü dize içinde var. Yukarıdaki ilk akıl sağlığı kontrolü budur.

kopyalama ve yapıştırma iyi çalışıyor ile swift 3.0.

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
    }

Umarım size yardımcı olur.


7
Bu 2 satırı if (textField == _ssn) {} ile sararak ve YES dönüşü ekleyerek bir çözüm buldu; diğer tüm UITextField öğelerinin herhangi bir kısıtlama olmaksızın metni kabul etmesine izin verecek olan yöntemin sonunda. Şık!
Kyle Clegg

55
İyi cevap, ama üçlü operatör gereksiz; sadece koyabilirsinizreturn newLength <= 25;
jowie

2
Ya sadece metnin metin alanının çerçevesi üzerine dökülmesini istemiyorsanız; tüm karakterler aynı genişlikte değil, değil mi?
Morkrom

2
İPad UITextFieldiOS 8.1'de test edilen @bcherry'den bahsedildiği gibi gerçekten bir geri alma hatası var . (Yorum yapmak için +1). En çok oy alan cevap olduğu için yazar bu konuda bir şeyler ekler mi? Bir düzenleme yapmaktan mutluyum, ancak benimki düzenli olarak reddediliyor gibi görünüyor! :-)
Benjohn

8
@bherry Swift'te geri alma vakası kontrolü emoji girişini bozuyor gibi görünüyor. Sayım (textField.text), gerçekten objm / uikit raporlaması aralığıyla eşleşecek şekilde (textField.text.utf16) sayılmamalı mı (Swift'in dizelerdeki sayım değişkenine karşı)?
rcw3

62

Hızlı 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
    }
}

Düzenleme: bellek sızıntısı sorunu düzeltildi.

resim açıklamasını buraya girin


Harika bir fikir Frouo! Cevabımı, UITextView örnekleri gibi şeyler için de kullanılabilir ve bir UITextField uzantısında bu String uzantıları yararlanmak için bir kolaylık işlevi eklemek için maxLength kırpma bir String uzantısına taşımak için üzerine genişletti.
Scott Gardner

1
Bu genel değişken, tüm metin görünümlerine (köklere kadar denetimlere referans veren) referanslar tutarak bellek sızıntıları oluşturmuyor mu?
Ixx

3
@Ixx Belirttiğiniz bellek sızıntısı sorununu düzeltmek için düzenledim + hızlı 3. Teşekkürler
frouo

1
başarmanın en güzel yolu! Teşekkürler
Victor Choy

kimse bana nesnel sürümünü sağlayabilir
MRizwan33

56

Teşekkür ederim ağustos! ( Yayınla )

Bu hangi ile sona erdi kodudur:

#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
Ne yazık ki, bu çözüm kullanıcıların bir metin alanına kopyalayıp yapışmasını durduramadığından, sınırı aşmalarına izin vermemektedir. Orak'ın cevabı bu durumla doğru bir şekilde başa çıkıyor.
Karınca

5
NO veya YES döndürmek için if ifadesine sahip kişilerde ne var? Şunu deneyin: return! (TextField.text.length> = MAX_LENGTH && range.length == 0);
Matt Parkins

veya bureturn textField.text.length < MAX_LENGTH || range.length != 0;
igrek

22

Ağustos yanıtını tamamlamak için , önerilen işlevin olası bir uygulaması ( UITextField temsilcisine bakın ).

Domness kodunu test etmedim , ancak kullanıcı sınıra ulaşırsa benim sıkışıp kalmaz ve daha küçük veya eşit olanın yerini alan yeni bir dize ile uyumludur.

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

Bunu doğrudan yapamazsınız - maxLength özniteliği UITextFieldyoktur , ancak temsilciyi ayarlayabilir , ardından şunu kullanabilirsiniz:UITextField's

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

5
Kabul ediyorum, bu en iyi yol, ama biraz hack kalır. Apple'a metin uzunluğu için bir özellik görmek istediğiniz bir hata raporu gönderin. Kesinlikle bununla da ilgileniyorum.
avocade

5
@ avocade, bu bir hack değil: Apple'ın sizin için yapması gereken temel çerçeve kodunu yapmanız gereken bir örnek. İOS SDK'sında bunun birçok örneği var.
Dan Rosenstark

13

Genellikle farklı uzunlukta birden çok giriş alanınız vardır.

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

En iyi yol, metin değiştirmeyle ilgili bir bildirim ayarlamaktır. Gözlerinde farklı -awakeFromNibgörünümünüzü kontrolör yönteminin size isteyeceksiniz:

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

Sonra aynı sınıfta ekleyin:

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

Ardından, çıkış myTextFieldnoktanızı bağlayın UITextFieldve sınıra ulaştıktan sonra başka karakter eklemenize izin vermez. Bunu dealloc yönteminize eklediğinizden emin olun:

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

Her ne kadar hataları kaldırmak için bunu yaptım> myTextField.text = [myTextField.text substringToIndex: limit];
Luke

11

Bu UITextFieldLimit alt sınıfını oluşturdum :

  • Birden çok metin alanı desteklenir
  • Metin uzunluğu sınırını ayarlama
  • Macun önleme
  • Metin alanında sol karakterlerin bir etiketini görüntüler, düzenlemeyi durdurduğunuzda gizlenir.
  • Hiç karakter kalmadığında animasyonu sallayın.

Kepçe UITextFieldLimit.hve UITextFieldLimit.mbu GitHub deposundan:

https://github.com/JonathanGurebo/UITextFieldLimit

ve test etmeye başlayın!

Film şeridi tarafından oluşturulan UITextField öğenizi işaretleyin ve Kimlik Denetçisi'ni kullanarak alt sınıfıma bağlayın:

Kimlik Müfettişi

Daha sonra bunu bir IBOutlet'e bağlayabilir ve sınırı ayarlayabilirsiniz (varsayılan değer 10'dur).


ViewController.h dosyanız şunları içermelidir: (ayarı değiştirmek gibi, sınır gibi)

#import "UITextFieldLimit.h"

/.../

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

ViewController.m dosyanız olmalıdır @synthesize textFieldLimit.


ViewController.m dosyanızdaki metin uzunluğu sınırını ayarlayı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.
}

Umarım sınıf sana yardım eder. İyi şanslar!


Karakter sınırlamasının küçük ihtiyacı için, bence sınıfınızı eklemeniz aşırıya kaçabilir.
Domness

Hala çaba takdir.
Orakçı

11

Bu sorunu çözmek için yeterli olmalıdır (4'ü u istediğiniz sınıra göre değiştirin). IB'ye delege eklediğinizden emin olun.

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

9

Uzantısı altında kullanın maksimum karakter uzunluğunu ayarlamak için UITextFieldve 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
        }
    }

Sınırı aşağıda ayarlayabilirsiniz.

resim açıklamasını buraya girin


farklı uzunluklara ihtiyaç duyan birçok metin alanı olduğunda çok iyi bir çözüm, teşekkürler çok teşekkürler
Carlos Norena

Metin alanı ve metin görünümü kontrolü karakter giriş sınırı için gerçekten harika bir çözüm. Onun kod satırlarını kaydetmek ve geliştirici için de zaman ... :)
Sandip Patel - SM

Bu bulduğum diğer çözümlerden daha iyi çalışıyor. Örneğin, metin alanınızda emojiler varsa, bulduğum diğer uzantılar düzenleme sırasında satırın sonuna atlar. Ancak kodunuz bunu yapmaz. Teşekkürler!
Phontaine Judd

7

Gelecekteki dize uzunluğunu hesaplamak üzere olacak gerçek dize değiştirme simüle:

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

Swift 3 sürümü // ***** Bu Swift 2.x ile ÇALIŞMAZ! ***** //

Önce yeni bir Swift dosyası oluşturun: TextFieldMaxLength.swift ve ardından aşağıdaki kodu ekleyin:

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

ve sonra herhangi bir TextField öğesini seçtiğinizde Storyboard'da yeni bir alan (Maks Uzunluk) göreceksiniz

daha fazla sorunuz varsa bu bağlantıyı kontrol edin: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields edilmiş maksimum uzunlukta görsel-stüdyo tarzı /


Uyarı, bu küresel değişken tüm metin görünümlerine referanslar tutarak bellek sızıntıları yaratır.
frouo

6

Arabirim oluşturucuyu kullanarak, işlevinizin herhangi birinde "Düzenleme değiştirildi" etkinliğini bağlayabilir ve alabilirsiniz. Şimdi orada uzunluğu kontrol edebilirsiniz

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

Aşağıdaki kod, sickp'in cevabına benzer, ancak kopyala-yapıştır işlemlerini doğru şekilde yapar. Sınırdan daha uzun bir metin yapıştırmaya çalışırsanız, aşağıdaki kod yapıştırma işlemini tamamen reddetmek yerine metni sınıra sığacak şekilde keser.

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

Swift'de maksimum uzunluğu ayarlamak için genel bir çözüm var . IBInspectable ile Xcode Özellik Denetçisi'ne yeni Özellik ekleyebilirsiniz.resim açıklamasını buraya girin

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
    }

}

Temiz ve mükemmel bir çözüm
Eduardo

Bir global alanda bir UITextField tutmak, UIViewController kapatıldıktan sonra bile bellekte kalır. Bu bir bellek sızıntısı. Bu yöntemi kullanmayın.
Gunhan

5

Herhangi bir uzunlukta dizelerin kesilmiş ve yapıştırılması ile çalışmak için, işlevi aşağıdaki gibi bir şeye değiştirmenizi öneririm:

#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

Hızlı 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
}

Neden guard?
oddRaven

metnin sıfır olup olmadığını kontrol edin, isterseniz, @oddRaven
Shan Ye

3

Swift 2.0 +

Her şeyden önce bu işlem için bir sınıf oluşturun. Buna StringValidator.swift diyelim.

Sonra aşağıdaki kodu içine yapıştırı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
}

}

Şimdi sınıfı kaydedin .....

Kullanımı ..

Şimdi viewController.swift sınıfına gidin ve metin alanınızın çıkışlarını şu şekilde yapın:

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

Şimdi metin alanının shouldChangeCharactersInRange yöntemine gidin ve aşağıdaki gibi kullanın.

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
    }

}

Temsilci protokolünü / metin alanları yöntemlerini ayarlamayı unutmayın.

Bu konuyu açıklamama izin verin ... Başka bir sınıfın içine yazdığım ipin basit uzantı sürecini kullanıyorum. Şimdi sadece kontrol ve maksimum değer ekleyerek onlara gereken başka bir sınıftan bu uzantı yöntemleri çağırıyorum.

Özellikleri...

  1. Belirli bir metin alanının maksimum sınırını belirler.
  2. Belirli bir metin alanı için kabul edilen anahtarların türünü ayarlayacaktır.

Türleri ...

includeOnlyCharactersIn // Yalnızca Karakterleri kabul eder.

includeCharactersIn // Karakterlerin birleşimini kabul eder

doesNotContainsCharactersIn // Karakterleri kabul etmeyecek

Umarım bu yardımcı oldu .... Teşekkürler ..


3

hızlı 3.0

Dizeyi karakter sınırlarınızdan daha fazla yapıştırdığınızda bu kod iyi çalışıyor.

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
    }

Oylarınız için teşekkürler. :)


2
UITextView değil, UITextField.
Jonny

3

@Frouo'ya dayalı ek bir cevap veriyorum. Cevabının en güzel yol olduğunu düşünüyorum. Tekrar kullanabileceğimiz ortak bir kontrol olduğundan.

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

Bu, UITextField üzerinde maksimum uzunluğu işlemenin doğru yoludur, dönüş anahtarının ilk yanıtlayıcı olarak metin alanından istifa etmesini sağlar ve kullanıcının sınıra ulaştığında geri almasını sağlar

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

Peki ya bu basit yaklaşım. Benim için iyi çalışıyor.

extension UITextField {

    func  charactersLimit(to:Int) {

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

Sonra:

someTextField.charactersLimit(to:16)

1

Diğer yanıtlar, kullanıcının panodan uzun bir dize yapıştırabileceği durumu ele almaz. Uzun bir dize yapıştırırsam, sadece kesilmiş ancak gösterilmelidir. Temsilcinizde bunu kullanı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

1 satır kod aşağı var :)

Metin görünümünüzün temsilcisini "self" olarak ayarlayın, ardından <UITextViewDelegate>.h ve .m kodunuza aşağıdaki kodu ekleyin.

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

Bu kod, yeni karakterler yazmak, karakterleri silmek, karakterleri seçmek, yazmak veya silmek, karakterleri seçmek ve kesmek, genel olarak yapıştırmak ve karakterleri seçmek ve yapıştırmaktan sorumludur.

Bitti!






Alternatif olarak, bu kodu bit işlemleri ile yazmanın başka bir yolu da

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

Açık bu özelliği (ve çok daha fazlası) özelliği ile sunan bir UITextField alt sınıfı, STATextField kaynaklı maxCharacterLength.


1

şimdi kaç karakter istersen sadece değer ver

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

Bu kodu burada kullanın RESTRICTED_LENGTH, metin alanı için kısıtlamak istediğiniz uzunluktur.

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

Swift'te sayı tuş takımını kullanırken 8 karakterlik bir sınır için yaptım.

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

Silme düğmesinin sayısal tuş takımında çalışmasına izin vermek için dize! = "" İçin test yapmak zorunda kaldım, aksi takdirde maksimum değerine ulaştıktan sonra metin alanındaki karakterlerin silinmesine izin vermezdi.


1

Xamarin için:

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

1

Bir maxLength özelliği eklemek için bir UITextField uzantısı uyguladım.

Xcode 6 IBInspectables tabanlıdır, böylece Arayüz oluşturucuda maxLength sınırını ayarlayabilirsiniz.

İşte uygulama:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.