티스토리 뷰

UITextFiled나 UITextView에서 입력 글자 제한을 해야되는 경우가 있다.



UITextFieldDelegate의 shouldChangeCharactersIn 메서드를 이용해서 아래와 같이 사용하는게 보통의 경우이다.

기존 textField의 텍스트와 새로 입력 받은 string을 합쳐서 길이를 제한하는 코드이다.


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

    guard let text = textField.text as NSString? else {return false}

    let newString = text.replacingCharacters(in: range, with: string)

    return newString.characters.count <= 6

}


하지만 위와 같이 사용했을 경우 아래와 같이 모음을 입력할때 더 이상 입력 받을 수 없는 오류가 있다.

"가나다라ㅁ" + "ㅏ" 


위와 같은 오류를 보완하고자 아래와 같이 구현해 보았다.



먼저 IBOutlet으로 UITextField를 연결하고 상수로 최대치를 편하게 바꿀수 있게 전역변수 선언을 하였다.

@IBOutlet fileprivate weak var tfLimitLength: UITextField!

private let MAX_LENGTH = 5


viewDidLoad에서 UITextFieldDelegate를 연결하고 UITextFieldTextDidChange를 NotificationCenter에 등록한다.

override func viewDidLoad() {

    super.viewDidLoad()

    // Do any additional setup after loading the view, typically from a nib.

    

    tfLimitLength.delegate = self

    NotificationCenter.default.addObserver(self,

                                           selector: #selector(textDidChange(_:)),

                                           name: NSNotification.Name.UITextFieldTextDidChange,

                                           object: tfLimitLength)

}


UITextFieldDelegate의 아래 메서드에서는 범위가 초과된 이후에 중간에 입력하는 값을 막게 하였다.

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

    guard let text = textField.text else {return false}

    

    // 중간에 추가되는 텍스트 막기

    if text.characters.count >= MAX_LENGTH && range.length == 0 && range.location < MAX_LENGTH {

        return false

    }

    

    return true

}


NotificationCenter에 등록된 아래 메서드에서 범위를 초과하는 텍스트를 자르도록 하였다.

붙여넣기하는 행위로 인해 초과되는 텍스트까지 차단할 수 있다.

@objc private func textDidChange(_ notification: Notification) {

    if let textField = notification.object as? UITextField {

        if let text = textField.text {

            // 초과되는 텍스트 제거

            if text.characters.count >= MAX_LENGTH {

                let index = text.index(text.startIndex, offsetBy: MAX_LENGTH)

                let newString = text.substring(to: index)

                textField.text = newString

            }

        }

    }

}


간단한 예제 소스

UITextFieldDelegateExample.zip



추가로 몇 글자 이후 키보드가 내려가게 하고 싶다면 아래와 같이 간단히 할 수 있다.

인증번호를 받은 후 정해진 길이의 숫자를 입력 받은 후 키보드 내리기와 같은데에서 응용 할 수 있을꺼 같다.


먼저 IBOutlet으로 UITextField를 연결

@IBOutlet fileprivate weak var tfLimitLength: UITextField!


viewDidLoad에서 UITextFieldTextDidChange를 NotificationCenter에 등록

NotificationCenter.default.addObserver(self,

                                       selector: #selector(textDidChange(_:)),

                                       name: NSNotification.Name.UITextFieldTextDidChange,

                                       object: tfLimitLength)


NotificationCenter에 등록된 아래 메서드에서 범위를 초과하면 키보드 내리기

@objc private func textDidChange(_ notification: Notification) {

    if let textField = notification.object as? UITextField {

        if let text = textField.text {

            if text.characters.count >= 5 {

                textField.resignFirstResponder()

            }

        }

    }

}