UITextField의 최대 문자 길이 설정


답변:


1029

그동안 UITextField클래스에는 최대 길이 속성이 없습니다, 그것은 텍스트 필드의를 설정하여이 기능을 얻기 위해 상대적으로 간단 delegate하고 다음 대리자 메서드를 구현 :

목표 -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;
}

빠른

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
}

텍스트 필드가 변경되기 전에 UITextField는 지정된 텍스트 변경 해야하는지 대리인에게 묻습니다 . 이 시점에서 텍스트 필드는 변경되지 않았으므로 현재 길이와 삽입 할 문자열 길이 (복사 된 텍스트 붙여 넣기 또는 키보드를 사용하여 단일 문자 입력)를 빼고 범위 길이를 뺀 것입니다. 이 값이 너무 길면 (이 예에서는 25 자 이상) NO변경을 금지하기 위해 돌아가십시오 .

텍스트 필드의 끝에 단일 문자를 입력 range.location하면 현재 필드의 길이가되고 range.length어떤 것도 바꾸거나 삭제하지 않기 때문에 0이됩니다. 텍스트 필드의 중간에 삽입한다는 것은 다른 것을 의미하며 range.location여러 문자를 붙여 넣으면 string둘 이상의 문자가 있음을 의미 합니다.

단일 문자 삭제 또는 여러 문자 절단은 range길이가 0이 아닌 빈 문자열로 지정됩니다. 교체는 비어 있지 않은 문자열로 범위를 삭제하는 것입니다.

충돌하는 "실행 취소"버그에 대한 메모

주석에서 언급했듯이 UITextField충돌이 발생할 수 있는 버그 가 있습니다.

필드에 붙여 넣지 만 유효성 검사 구현으로 붙여 넣기가 금지 된 경우 붙여 넣기 작업은 여전히 ​​응용 프로그램의 실행 취소 버퍼에 기록됩니다. 당신이 후 (장치를 흔들어 실행 취소를 확인하여) 실행 취소를 해고하는 경우는 UITextField이 문자열 대체하려고 시도합니다 생각 이 빈 문자열 자체에 붙여 넣기합니다. 실제로 문자열을 자체적으로 붙여 넣지 않았기 때문에 충돌이 발생 합니다. 존재하지 않는 문자열의 일부를 바꾸려고 시도합니다.

다행스럽게도 UITextField이와 같이 자신을 죽이지 않도록 보호 할 수 있습니다 . 당신은 그것을 대체하는 제안의 범위가 있는지 확인해야 합니까 현재 문자열 내에 존재합니다. 이것이 위의 초기 상태 점검입니다.

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
    }

도움이 되길 바랍니다.


7
이 두 줄을 if (textField == _ssn) {}로 묶고 return YES를 추가하여 해결책을 찾았습니다. 메소드의 끝에는 다른 모든 UITextField가 제한없이 텍스트를 허용 할 수 있습니다. 맵시 있는!
Kyle Clegg

55
좋은 대답이지만 삼항 연산자는 불필요합니다. 당신은 그냥 넣을 수 있습니다return newLength <= 25;
jowie

2
텍스트가 텍스트 필드의 프레임 위로 넘치지 않게하려면 어떻게해야합니까? 모든 문자의 너비가 같은 것은 아닙니다.
Morkrom

2
@bcherry가 언급 한 것처럼 실행 취소 버그가 있습니다 – UITextFieldiPad iOS 8.1에서 테스트되었습니다 . (댓글을 달려면 +1). 작성자가 최고 등급의 답변이므로 이에 대해 뭔가 추가 하시겠습니까? 편집을하게되어 기쁘지만 정기적으로 거부당하는 것 같습니다! :-)
Benjohn

8
@bherry Swift에서 실행 취소 사례를 확인하면 이모티콘 입력이 중단 된 것 같습니다. 범위에서 objc / uikit보고와 일치하기 위해 count (textField.text)가 count (textField.text.utf16)가 아니어야합니까 (Swift의 문자열 수 계산 대)?
rcw3

62

스위프트 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
    }
}

편집 : 메모리 누수 문제가 해결되었습니다.

여기에 이미지 설명을 입력하십시오


좋은 생각 Frouo! maxLength 트리밍을 String 확장으로 이동하여 UITextView 인스턴스와 같은 것에 사용할 수 있고 UITextField 확장에서 이러한 String 확장을 활용할 수있는 편리한 함수를 추가하기 위해 대답을 확장했습니다.
Scott Gardner

1
이 전역 변수가 모든 텍스트 뷰에 대한 참조 (루트까지 슈퍼 뷰를 참조)를 보유함으로써 메모리 누수를 생성하지는 않습니다.
Ixx

3
@Ixx 내가 지적한 메모리 누수 문제를 해결하기 위해 편집했습니다 + 빠른 3입니다. 감사합니다
frouo

1
그것을 달성하는 가장 아름다운 방법! 감사합니다
Victor Choy

누구든지 나에게 객관적인 버전을 제공 할 수
있습니까

56

8 월 감사합니다! ( 포스트 )

이것은 내가 끝낸 코드입니다.

#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
불행히도이 솔루션은 사용자가 텍스트 필드에 복사하여 붙여 넣기를 중지하지 못하므로 제한을 무시할 수 있습니다. Sickpea의 답변은 이러한 상황에 올바르게 대처합니다.
Ant

5
if 문을 가지고 NO 또는 YES를 반환하는 사람들은 무엇입니까? 이것을 시도하십시오 : return! (textField.text.length> = MAX_LENGTH && range.length == 0);
Matt Parkins

또는 이것return textField.text.length < MAX_LENGTH || range.length != 0;
igrek

22

제안 된 함수의 가능한 구현 인 8 월 답변 을 완료하려면 ( UITextField의 delegate 참조 ).

나는 코드를 테스트 하지 않았지만 사용자가 한계에 도달하면 멈추지 않으며 더 작거나 같은 것을 대체하는 새로운 문자열과 호환됩니다.

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

직접 할 수 UITextField는 없습니다 -maxLength 속성이 없지만 UITextField's대리자를 설정 한 후 다음을 사용할 수 있습니다.

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

5
나는 이것이 최선의 방법이라고 동의하지만 그것은 약간의 해킹을 유지합니다. 텍스트 길이 속성을보고 싶은 버그 보고서를 Apple에 제출하십시오. 나는 이것에도 확실히 관심이 있습니다.
avocade

5
@avocade, 그것은 해킹이 아닙니다 : 그것은 Apple이 당신을 위해해야했던 기본 프레임 워크 코드를 수행 해야하는 예입니다. iOS SDK에는 이것에 대한 많은 예가 있습니다.
Dan Rosenstark

13

종종 길이가 다른 여러 입력 필드가 있습니다.

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

가장 좋은 방법은 텍스트 변경에 대한 알림을 설정하는 것입니다. 당신의에서 -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를 귀하 의 콘센트 에 연결 UITextField하면 한도에 도달 한 후 더 이상 문자를 추가 할 수 없습니다. 이것을 dealloc 메소드에 추가하십시오 :

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

오류를 제거하기 위해이 작업을 수행했지만> myTextField.text = [myTextField.text substringToIndex : limit];
Luke

11

UITextFieldLimit 하위 클래스를 만들었습니다 .

  • 여러 개의 텍스트 필드 지원
  • 텍스트 길이 제한 설정
  • 붙여 넣기 방지
  • 텍스트 필드 안에 왼쪽 문자 레이블을 표시하고 편집을 중지하면 숨겨집니다.
  • 남은 캐릭터가 없을 때 애니메이션을 흔 듭니다.

그랩 UITextFieldLimit.hUITextFieldLimit.m이 GitHub의 저장소에서를 :

https://github.com/JonathanGurebo/UITextFieldLimit

테스트 시작!

스토리 보드에서 만든 UITextField를 표시하고 Identity Inspector를 사용하여 내 하위 클래스에 연결하십시오.

신원 관리자

그런 다음 IBOutlet에 연결하고 한계를 설정할 수 있습니다 (기본값은 10).


ViewController.h 파일에는 다음이 포함되어야합니다 (한계와 같이 설정을 수정하지 않으려는 경우).

#import "UITextFieldLimit.h"

/.../

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

ViewController.m 파일이 있어야합니다 @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.
}

수업이 도움이 되길 바랍니다. 행운을 빕니다!


문자 수 제한이 적기 때문에 클래스를 추가하는 것이 너무 과도하다고 생각합니다.
Domness

여전히 노력에 감사드립니다.
Reaper

11

이것은 문제를 해결하기에 충분해야합니다 (원하는 한계 값으로 4를 대체하십시오). IB에 대리인을 추가하십시오.

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

9

아래 확장명을 사용하여 a UITextField및 의 최대 문자 길이를 설정하십시오 UITextView.

스위프트 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
        }
    }

아래에서 제한을 설정할 수 있습니다.

여기에 이미지 설명을 입력하십시오


다른 길이를 필요로하는 텍스트 필드가 많을 때 훌륭한 솔루션 덕분에 최고의 답변
Carlos Norena

텍스트 필드 및 텍스트 뷰 제어 문자 입력 제한에 대한 훌륭한 솔루션입니다. 개발자의 코드 라인과 시간도 절약 할 수 있습니다 ... :)
Sandip Patel-SM

이것은 내가 찾은 다른 솔루션보다 잘 작동합니다. 예를 들어, 텍스트 필드에 그림 이모티콘이있는 경우 편집 한 다른 확장자는 줄 끝으로 건너 뜁니다. 그러나 코드는 그렇게하지 않습니다. 감사!
폰 타인 저드

7

미래의 문자열 길이를 계산하기 위해 실제 문자열 교체를 시뮬레이션합니다.

- (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 버전 // ***** Swift 2.x에서는 작동하지 않습니다! ***** //

먼저 새 Swift 파일 (TextFieldMaxLength.swift)을 만든 다음 아래 코드를 추가하십시오.

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

TextField를 선택하면 Storyboard에 새 필드 (최대 길이)가 표시됩니다.

그래도 더 궁금한 점이 있으면 다음 링크를 확인 하십시오. -최대 길이-시각-스튜디오 스타일 /


경고,이 전역 변수는 모든 텍스트 뷰에 대한 참조를 보유하여 메모리 누수를 만듭니다.
frouo

6

인터페이스 빌더를 사용하면 모든 기능에서 "편집 된 변경 사항"이벤트를 링크하고 얻을 수 있습니다. 이제 길이를 확인할 수 있습니다

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

다음 코드는 sickp의 답변과 비슷하지만 복사-붙여 넣기 작업을 올바르게 처리합니다. 한도보다 긴 텍스트를 붙여 넣으려고하면 다음 코드는 붙여 넣기 작업을 완전히 거부하지 않고 한도에 맞게 텍스트를 자릅니다.

- (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에서 최대 길이를 설정하는 일반적인 해결책 이 있습니다 . IBInspectable을 통해 Xcode 속성 관리자에서 새 속성을 추가 할 수 있습니다.여기에 이미지 설명을 입력하십시오

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
    }

}

깨끗하고 완벽한 솔루션
Eduardo

UITextField를 전역 필드에 유지하면 UIViewController가 해제 된 후에도 메모리에 유지됩니다. 이것은 메모리 누수입니다. 이 방법을 사용하지 마십시오.
Gunhan 2019

5

길이에 관계없이 문자열을 잘라내어 붙여 넣으려면 기능을 다음과 같이 변경하는 것이 좋습니다.

#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

스위프트 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
}

guard?
oddRaven

텍스트가 없는지 확인하십시오. 원한다면 @oddRaven
Shan Ye

3

스위프트 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
}

}

이제 수업을 저장하십시오 .....

용법..

이제 viewController.swift 클래스로 이동하여 텍스트 필드의 콘센트를 ..

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

이제 텍스트 필드의 shouldChangeCharactersInRange 메소드로 이동하여 다음과 같이 사용하십시오.

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 // 문자를 허용하지 않습니다

도움이 되었기를 바랍니다 .. 감사합니다 ..


3

스위프트 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
    }

투표 해 주셔서 감사합니다. :)


2
UITextView가 아닌 ​​UITextField입니다.
Jonny

3

@Frouo를 기반으로 보충 답변을 제공합니다. 나는 그의 대답이 가장 아름다운 방법이라고 생각합니다. 우리가 재사용 할 수있는 일반적인 제어 수단이라는 점을 명심하십시오.

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

이것은 UITextField에서 최대 길이를 처리하는 올바른 방법입니다. 리턴 키를 사용하여 텍스트 필드를 첫 번째 응답자로 사임하고 사용자가 한계에 도달하면 백 스페이스를 허용합니다.

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

이 간단한 접근법은 어떻습니까? 그것은 나를 위해 잘 작동합니다.

extension UITextField {

    func  charactersLimit(to:Int) {

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

그때:

someTextField.charactersLimit(to:16)

1

다른 답변은 사용자가 클립 보드에서 긴 문자열을 붙여 넣을 수있는 경우를 처리하지 않습니다. 긴 문자열을 붙여 넣으면 잘리지 만 표시되어야합니다. 대리인에게 이것을 사용하십시오.

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

코드 한 줄로 줄였습니다 :)

텍스트 뷰의 델리게이트를 "self"로 설정 한 다음 <UITextViewDelegate>.h에 .h에 다음 코드 를 추가하고 .m에 다음 코드 를 추가 하십시오. 최대 숫자를 원하는대로 숫자 "7"을 조정할 수 있습니다.

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

이 코드는 새 문자 입력, 문자 삭제, 문자 선택 후 입력 또는 삭제, 문자 선택 및 잘라 내기, 일반적인 붙여 넣기 및 문자 선택 및 붙여 넣기를 설명합니다.

끝난!






또는 비트 연산으로이 코드를 작성하는 또 다른 멋진 방법은 다음과 같습니다.

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

이제 얼마나 많은 문자를 원합니까?

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

여기서이 코드를 사용하십시오. 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;

}

1

숫자 패드를 사용할 때 Swift에서 8 자 제한을 위해이 작업을 수행했습니다.

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

삭제 버튼이 숫자 패드에서 작동하도록 문자열! = ""을 테스트해야했습니다. 그렇지 않으면 텍스트 필드의 최대 문자에 도달 한 후 문자를 삭제할 수 없습니다.


1

Xamarin의 경우 :

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

1

maxLength 속성을 추가하기 위해 UITextField Extension을 구현했습니다.

Xcode 6 IBInspectables를 기반으로하므로 인터페이스 빌더에서 maxLength 한계를 설정할 수 있습니다.

구현은 다음과 같습니다.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.