최대 길이 UITextField


120

swift를 사용하여 UITextField에 입력 할 수있는 최대 문자 수를 설정하는 방법을 시도했을 때 ? , 10 개의 문자를 모두 사용하면 문자도 지울 수 없다는 것을 알았습니다.

내가 할 수있는 유일한 일은 작업을 취소하는 것입니다 (모든 문자를 함께 삭제).

누구든지 키보드를 차단하지 않는 방법을 알고 있습니까 (다른 문자 / 기호 / 숫자를 추가 할 수 없지만 백 스페이스를 사용할 수 있음)?

답변:


294

Swift 5 및 iOS 12 textField(_:shouldChangeCharactersIn:replacementString:)에서 UITextFieldDelegate프로토콜의 일부인 다음 메소드 구현을 시도하십시오 .

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let textFieldText = textField.text,
        let rangeOfTextToReplace = Range(range, in: textFieldText) else {
            return false
    }
    let substringToReplace = textFieldText[rangeOfTextToReplace]
    let count = textFieldText.count - substringToReplace.count + string.count
    return count <= 10
}
  • 이 코드의 가장 중요한 부분에서 변환입니다 range( NSRange에) rangeOfTextToReplace( Range<String.Index>). 이 변환이 중요한 이유를 이해하려면 이 비디오 자습서 를 참조하십시오 .
  • 이 코드가 제대로 작동하도록하려면 textFieldsmartInsertDeleteType값 도로 설정해야 합니다 UITextSmartInsertDeleteType.no. 이렇게하면 붙여 넣기 작업을 수행 할 때 (원치 않는) 추가 공간이 삽입되는 것을 방지 할 수 있습니다.

어떻게 구현하는 방법을 보여줍니다 아래의 완전한 샘플 코드 textField(_:shouldChangeCharactersIn:replacementString:)A의 UIViewController:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var textField: UITextField! // Link this to a UITextField in Storyboard

    override func viewDidLoad() {
        super.viewDidLoad()

        textField.smartInsertDeleteType = UITextSmartInsertDeleteType.no
        textField.delegate = self
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let textFieldText = textField.text,
            let rangeOfTextToReplace = Range(range, in: textFieldText) else {
                return false
        }
        let substringToReplace = textFieldText[rangeOfTextToReplace]
        let count = textFieldText.count - substringToReplace.count + string.count
        return count <= 10
    }

}

이 코드를 뷰 컨트롤러 클래스에 넣습니까? 아니면 연결을해야합니까?
Isaac Wasserman

누군가 조건을 정해야한다면 .. 이렇게 할 수 있습니다 ... if (textField .isEqual (mobileNumberTextfield)) {guard let text = textField.text else {return true} let newLength = text.characters.count + string.characters.count-range.length return newLength <= limitLength; } return true;
Narasimha Nallamsetty 2015

5
Swift 4의 경우 text.characters.count더 이상 사용되지 않음text.count
Mohamed Salah

47

나는 이것을 이렇게한다 :

func checkMaxLength(textField: UITextField!, maxLength: Int) {
    if (countElements(textField.text!) > maxLength) {
        textField.deleteBackward()
    }
}

코드는 나를 위해 작동합니다. 하지만 저는 스토리 보드로 작업합니다. Storyboard에서 변경된 편집시 뷰 컨트롤러의 텍스트 필드에 대한 작업을 추가합니다 .


1
countElements가 Swift 2에서 count로 변경되었지만 그 변경은 저에게 효과적입니다!
John

1
감사합니다. countElements가 변경되었으므로 이제 textField.text? .characters.count를 사용할 수 있습니다.
Anibal R.

1
Tks,이 변경으로 훌륭하게 작동했습니다. Swift 2의 countElements (textField.text!)는 다음과 같습니다. textField.text? .characters.count
kha

33

Swift 4 업데이트

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
     guard let text = textField.text else { return true }
     let newLength = text.count + string.count - range.length
     return newLength <= 10
}

15

@Martin 답변에서 자세한 내용 추가

// linked your button here
@IBAction func mobileTFChanged(sender: AnyObject) {
    checkMaxLength(sender as! UITextField, maxLength: 10)
}

// linked your button here
@IBAction func citizenTFChanged(sender: AnyObject) {
    checkMaxLength(sender as! UITextField, maxLength: 13)
}

func checkMaxLength(textField: UITextField!, maxLength: Int) {
    // swift 1.0
    //if (count(textField.text!) > maxLength) {
    //    textField.deleteBackward()
    //}
    // swift 2.0
    if (textField.text!.characters.count > maxLength) {
        textField.deleteBackward()
    }
}

1
count (textField.text!)는 오류를 제공합니다. ! 당신은 textField.text 할 .characters.count을 사용해야합니다
레지스 세인트 Gelais

1
RegisSt-Gelais @ 덕분에, 그것은 이미 오래된 대답은, 내가 지금으로 업데이트
Sruit A.Suk에게

11

Swift 4에서

텍스트 필드 10 자 제한 및 삭제 (백 스페이스) 허용

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField ==  userNameFTF{
            let char = string.cString(using: String.Encoding.utf8)
            let isBackSpace = strcmp(char, "\\b")
            if isBackSpace == -92 {
                return true
            }
            return textField.text!.count <= 9
        }
        return true
    }

8
func checkMaxLength(textField: UITextField!, maxLength: Int) {
        if (textField.text!.characters.count > maxLength) {
            textField.deleteBackward()
        }
}

IOS 9의 작은 변화


8

스위프트 3

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

            let nsString = NSString(string: textField.text!)
            let newText = nsString.replacingCharacters(in: range, with: string)
            return  newText.characters.count <= limitCount
    }

8

UITextField를 확장하고 @IBInspectable처리 할 개체를 추가 할 수 있습니다 .

SWIFT 5

import UIKit
private var __maxLengths = [UITextField: Int]()
extension UITextField {
    @IBInspectable var maxLength: Int {
        get {
            guard let l = __maxLengths[self] else {
                return 150 // (global default-limit. or just, Int.max)
            }
            return l
        }
        set {
            __maxLengths[self] = newValue
            addTarget(self, action: #selector(fix), for: .editingChanged)
        }
    }
    @objc func fix(textField: UITextField) {
        if let t = textField.text {
            textField.text = String(t.prefix(maxLength))
        }
    }
}

그 후에 속성 검사기에서 정의하십시오.

여기에 이미지 설명 입력

참조 스위프트 4 원래의 대답


2
멋지고 깨끗한 코드. 그러나 어떤 이유로 이로 인해 이모티콘을 사용할 때 이상한 편집 동작이 발생합니다. 편집을 시도 할 때마다 커서가 줄 끝으로 건너 뜁니다.
Phontaine Judd

5

마지막 문자를 덮어 쓰려면 :

let maxLength = 10

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

    if range.location > maxLength - 1 {
        textField.text?.removeLast()
    }

    return true
}

4

을 사용하여 솔루션을 게시 IBInspectable했으므로 인터페이스 빌더에서 또는 프로그래밍 방식으로 최대 길이 값을 변경할 수 있습니다. 여기에서 확인하세요


3

당신은 같은 빠른 5 빠른 4에서 사용할 수있는 울부 짖는 소리와 같은 이미지보기 여기에 이미지 설명 입력

  1. View Controller에 textField 추가
  2. ViewController에 텍스트에 연결
  3. ViewController에 코드 추가

     class ViewController: UIViewController , UITextFieldDelegate {
    
      @IBOutlet weak var txtName: UITextField!
    
      var maxLen:Int = 8;
    
     override func viewDidLoad() {
        super.viewDidLoad()
    
        txtName.delegate = self
       }
    
     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
         if(textField == txtName){
            let currentText = textField.text! + string
            return currentText.count <= maxLen
         }
    
         return true;
       }
    }

GitHub에서 전체 소스 양식을 다운로드 할 수 있습니다. https://github.com/enamul95/TextFieldMaxLen


1

이 게시물에 언급 된 UITextField에 대한 실행 취소 버그에주의하십시오. UITextField 의 최대 문자 길이 설정

여기에 신속하게 수정하는 방법이 있습니다.

if(range.length + range.location > count(textField.text)) {
        return false;
}

이모티콘과 같은 사용을 지원하고 싶다면 : if (range.length + range.location> count (textField.text.utf16)) {return false; }
AlexD

1
Here is my version of code. Hope it helps!

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        let invalidCharacters = NSCharacterSet(charactersInString: "0123456789").invertedSet

        if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex))
        {
            return false
        }

        if (count(textField.text) > 10  && range.length == 0)
        {
            self.view.makeToast(message: "Amount entry is limited to ten digits", duration: 0.5, position: HRToastPositionCenter)
            return false
        }
        else
        {

        }

        return true
    }

1
:) 토스트 UIView의 확장과 같은 I
레지스 세인트 Gelais

1

내 앱 중 하나에서이 프로토콜 / 확장 프로그램을 사용해 왔는데 좀 더 읽기 쉽습니다. 백 스페이스를 인식하고 문자가 백 스페이스 일 때 명시 적으로 알려주는 방식이 마음에 듭니다.

고려해야 할 몇 가지 사항 :

1.이 프로토콜 확장을 구현하는 것은 문자 제한을 지정해야합니다. 이는 일반적으로 ViewController가 될 것이지만, 문자 제한을 계산 된 속성으로 구현하고 다른 것을 반환 할 수 있습니다 (예 : 모델 중 하나의 문자 제한).

2. 텍스트 필드의 shouldChangeCharactersInRange 델리게이트 메서드 내에서이 메서드를 호출해야합니다. 그렇지 않으면 false를 반환하여 텍스트 입력을 차단할 수 없습니다.

3. 백 스페이스 문자를 허용 할 수 있습니다. 그래서 백 스페이스를 감지하는 추가 기능을 추가했습니다. shouldChangeCharacters 메소드는이를 확인하고 초기에 'true'를 반환 할 수 있으므로 항상 백 스페이스를 허용합니다.

protocol TextEntryCharacterLimited{
    var characterLimit:Int { get } 
}

extension TextEntryCharacterLimited{

    func charactersInTextField(textField:UITextField, willNotExceedCharacterLimitWithReplacementString string:String, range:NSRange) -> Bool{

        let startingLength = textField.text?.characters.count ?? 0
        let lengthToAdd = string.characters.count
        let lengthToReplace = range.length

        let newLength = startingLength + lengthToAdd - lengthToReplace

        return newLength <= characterLimit

    }

    func stringIsBackspaceWith(string:String, inRange range:NSRange) -> Bool{
        if range.length == 1 && string.characters.count == 0 { return true }
        return false
    }

}

관심있는 사람이 있다면이 문자 제한 동작 중 일부를 가져와 iOS 프레임 워크에 넣은 Github 저장소가 있습니다. 문자 제한을 얼마나 초과했는지를 보여주는 Twitter와 같은 문자 제한 디스플레이를 얻기 위해 구현할 수있는 프로토콜이 있습니다.

Github의 CharacterLimited 프레임 워크


1

델리게이트는 일대일 관계이고 다른 이유로 다른 곳에서 사용하고 싶을 수 있으므로 설정 내에서이 코드를 추가하여 텍스트 필드 길이를 제한하고 싶습니다.

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        setup()
    }

    required override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    func setup() {

        // your setup...

        setMaxLength()
    }

    let maxLength = 10

    private func setMaxLength() {
            addTarget(self, action: #selector(textfieldChanged(_:)), for: UIControlEvents.editingChanged)
        }

        @objc private func textfieldChanged(_ textField: UITextField) {
            guard let text = text else { return }
            let trimmed = text.characters.prefix(maxLength)
            self.text = String(trimmed)

        }

0

나는 이것을 사용하고있다;

3 자 제한

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

        if let txt = textField.text {
            let currentText = txt + string
            if currentText.count > 3 {
                return false
            }
            return true
        }
        return true
    }

0

스위프트 5

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let MAX_LENGTH = 4
        let updatedString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        return updatedString.count <= MAX_LENGTH
    }

-3

기존 문자열과 입력 값이 10보다 큰지 확인해야합니다.

   func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange,    replacementString string: String!) -> Bool {
      NSUInteger newLength = textField.text.length + string.length - range.length;
      return !(newLength > 10)
   }

5
코드가 잘못되었습니다. 1. Swift에서 let 또는 var로 상수 또는 변수를 선언해야합니다 (NSUInteger 아님). 2. textField.text 및 string은 String 유형입니다. Length는 Swift에서 String의 속성 / 메서드가 아닙니다.
Imanou Petit 2014 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.