ios - قم بتعيين الحد الأقصى لطول حرف UITextField




objective-c cocoa-touch (20)

سويفت 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
    }

شكرا لتصويتك. :)

كيف يمكنني ضبط الحد الأقصى لعدد الأحرف في UITextField على iPhone SDK عند تحميل UIView ؟


سويفت 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
    }
}

تحرير: مشكلة تسرب الذاكرة الثابتة.


أفضل طريقة هي إعداد إشعار حول تغيير النص. في -awakeFromNib من طريقة تحكم وجهة نظرك سترغب في:

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

ثم في نفس الفئة إضافة:

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

ثم قم myTextField منفذ myTextField إلى myTextField الخاص بك ولن يسمح لك بإضافة أي أحرف إضافية بعد أن تصل إلى الحد الأقصى. تأكد من إضافة هذا إلى طريقة dealloc:

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

أقوم بمحاكاة استبدال السلسلة الفعلي الذي سيحدث ليحسب طول السلسلة المستقبلية:

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

استخدم هذا الرمز هنا RESTRICTED_LENGTH هو الطول الذي تريد تقييده في حقل النص.

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

}

الآن كم عدد الأحرف التي تريد فقط إعطاء القيم

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

باستخدام أداة إنشاء الواجهة ، يمكنك ربط الحدث والحصول على "تغييره" في أي من وظائفك. الآن يمكنك وضع التحقق من الطول

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

}

بينما لا تحتوي فئة UITextField على خاصية الطول الأقصى ، فمن السهل الحصول على هذه الوظيفة عن طريق تعيين delegate حقل النص وتنفيذ أسلوب التفويض التالي:

ج موضوعية

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

سريع

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

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

قبل تغيير حقل النص ، يطلب UITextField المفوض إذا كان يجب تغيير النص المحدد. لم يتغير حقل النص عند هذه النقطة ، لذلك نلتقط طوله الحالي وطول السلسلة التي نقوم بإدخالها (إما من خلال لصق النص المنسوخ أو كتابة حرف واحد باستخدام لوحة المفاتيح) ، مطروحًا منه طول النطاق. إذا كانت هذه القيمة طويلة جدًا (أكثر من 25 حرفًا في هذا المثال) ، فأرجع NO لحظر التغيير.

عند الكتابة في حرف واحد في نهاية حقل النص ، سيكون range.location هو طول الحقل الحالي ، وسوف يكون range.length 0 لأننا لا نقوم باستبدال / حذف أي شيء. الإدراج في منتصف حقل النص يعني مجرد نطاق مختلف. range.location ، ولصق حروف متعددة يعني أن string تحتوي على أكثر من حرف واحد.

يتم تحديد حذف أحرف مفردة أو قطع أحرف متعددة بواسطة range بطول غير صفري ، وسلسلة فارغة. الاستبدال هو مجرد حذف مجموعة مع سلسلة غير فارغة.

ملاحظة حول الخطأ "التراجع" المتعثر

كما هو مذكور في التعليقات ، هناك خلل مع UITextField يمكن أن يؤدي إلى تعطل.

إذا قمت بلصق الحقل ، ولكن تم منع اللصق من خلال تطبيق التحقق من الصحة ، فسيتم تسجيل عملية اللصق في مخزن التراجع للتطبيق. إذا قمت بعد ذلك UITextField التراجع (عن طريق هز الجهاز وتأكيد التراجع) ، UITextField استبدال السلسلة التي يعتقد أنها ألصقت نفسها بسلسلة فارغة. سينهار هذا لأنه لم يلصق السلسلة فعليًا في نفسه. سيحاول استبدال جزء من السلسلة غير موجود.

لحسن الحظ يمكنك حماية UITextField من قتل نفسه مثل هذا. تحتاج فقط إلى التأكد من أن النطاق الذي يقترح استبداله موجود ضمن سلسلته الحالية. هذا هو ما يفعله فحص التعقل الأولي أعلاه.

سويفت 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
    }

آمل أن تكون مفيدة لك.


شكرا لك أغسطس! ( Post )

هذا هو الرمز الذي انتهى به الأمر مع أي أعمال:

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

غالبًا ما يكون لديك حقول إدخال متعددة بطول مختلف.

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

لإكمال إجابة شهر أغسطس ، تنفيذ محتمل للوظيفة المقترحة (انظر مندوب UITextField ).

لم أختبر رمز domness ، ولكن لا تتعثر منجم إذا وصل المستخدم إلى الحد الأقصى ، وهو متوافق مع سلسلة جديدة تأتي باستبدال واحدة أصغر أو متساوية.

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

لا تتعامل الإجابات الأخرى مع الحالة حيث يمكن للمستخدم لصق سلسلة طويلة من الحافظة. إذا قمت بلصق سلسلة طويلة ، يجب أن يتم اقتطاعها فقط ولكن يتم عرضها. استخدم هذا في مندوبك:

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'

}

لجعله يعمل مع قص ولصق السلاسل من أي طول ، أقترح تغيير الوظيفة إلى شيء مثل:

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

لقد أنشأت this التصنيف الفرعي UITextFieldLimit:

  • حقول نصية متعددة مدعومة
  • قم بتعيين حد طول النص
  • معجون الوقاية
  • يعرض تصنيفًا للأحرف اليسرى داخل حقل النص ، ويتم إخفائه عند إيقاف التحرير.
  • اهتز الرسوم المتحركة عند عدم ترك أي شخص.

أمسك UITextFieldLimit.h و UITextFieldLimit.m من مستودع GitHub هذا:

this

والبدء في اختبار!

قم بتمييز UITextField الذي أنشأته في لوحة العمل واربطه بفئة فرعية باستخدام "مفتش الهوية":

ثم يمكنك ربطه بـ IBOutlet وتعيين الحد (الافتراضي هو 10).

يجب أن يحتوي ملف ViewController.h على: (إذا كنت ترغب في تعديل الإعداد ، مثل الحد)

#import "UITextFieldLimit.h"

/.../

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

يجب أن @synthesize textFieldLimit .

قم بتعيين حد طول النص في ملف ViewController.m الخاص بك:

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

آمل أن يساعدك الفصل. حظا طيبا وفقك الله!


لقد قمت بفتح مصادر فئة فرعية UITextField ، STATextField ، التي توفر هذه الوظيفة (وأكثر من ذلك بكثير) مع الخاصية maxCharacterLength .


هذا يحد من عدد الأحرف ، ولكن أيضًا تأكد من أنه يمكنك لصقها في الحقل حتى الحد الأقصى.

- (void)textViewDidChange:(UITextView *)textView
{
    NSString* str = [textView text];
    str = [str substringToIndex:MIN(1000,[str length])];
    [textView setText:str];

    if([str length]==1000) {
        // show some label that you've reached the limit of 1000 characters
    }
}

هناك حل عام لتحديد الطول الأقصى في سويفت. من خلال IBInspectable يمكنك إضافة سمة جديدة في Xcode Attribute Inspector.

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
    }

}

يجب أن يكون هذا كافيًا لحل المشكلة (استبدل 4 بالحد الذي تريده). فقط تأكد من إضافة مندوب في IB.

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

سويفت 2.0 +

أولا وقبل كل خلق فئة لهذه العملية. دعنا نسميها StringValidator.swift.

ثم قم بلصق التعليمة البرمجية التالية بداخله.

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
}

}

الآن احفظ الصف .....

استخدام ..

الآن انتقل إلى class view (viewController.swift) الخاص بك واجعل منافذ Textfield الخاصة بك هي ..

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

الآن انتقل إلى طريقة textfield'sChangeCharactersInRange واستخدامها كما يلي.

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
    }

}

لا تنسى تعيين بروتوكول / طرق تفويض الحقول النصية.

اسمحوا لي أن أشرح عن هذا ... أنا أستخدم عملية تمديد بسيطة من السلسلة التي كتبت داخل فئة أخرى. الآن أنا أقوم فقط بالاتصال بأساليب التمديد هذه من فئة أخرى حيث أحتاج إليها عن طريق إضافة الشيك والقيمة القصوى.

الميزات...

  1. سيتم تعيين الحد الأقصى لحقل نص معين.
  2. سيقوم بتعيين نوع من المفاتيح المقبولة لحقل نص معين.

أنواع ...

containsOnlyCharactersIn // يقبل الأحرف فقط.

containsCharactersIn/ يقبل مزيج من الأحرف

doesNotContainsCharactersIn // لن يقبل الأحرف

نأمل أن يكون هذا ساعد .... شكرا ..


سويفت 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
}




uitextfield