UITextField 를 쓰다보니 글자 수를 제한해야하는 경우가 생겼는데 그 방법을 한번 정리해보려한다.
우선 테스트를 위해 view 가운데에 UITextField 하나를 올려두었다.
class SettingViewController: UIViewController {
let textField: UITextField = {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.layer.cornerRadius = 4
textField.layer.borderWidth = 1
return textField
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(textField)
textField.delegate = self
NSLayoutConstraint.activate([
textField.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
textField.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
textField.widthAnchor.constraint(equalToConstant: 300),
textField.heightAnchor.constraint(equalToConstant: 100)
])
}
}
UITextField의 textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) 이 메소드를 확장시켜서 글자 수를 제한시킬거다. 해당 메소드의 첫번째 값은 나의 textField의 text, 두번째 값은 range의 location (범위), 세번째 값은 지정된 범위의 문자열입니다. (입력된 새 문자 하나만 포함) 이 메소드를 확장시켜서 사용하면 문자의 변경사항을 확인해서 처리시켜줄 수 있다.
...
textField.delegate = self // 델리게이트 위임
...
extension SettingViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard textField.text!.count < 10 else { return false } // 10 글자로 제한
return true
}
}
위의 코드로만 끝내면 10 글자 이후부터는 수정을 할 수가 없기 때문에 백스페이스 처리를 또 따로 해줘야한다..
...
textField.delegate = self // 델리게이트 위임
...
extension SettingViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// 백스페이스 처리
if let char = string.cString(using: String.Encoding.utf8) {
let isBackSpace = strcmp(char, "\\b")
if isBackSpace == -92 {
return true
}
}
guard textField.text!.count < 10 else { return false } // 10 글자로 제한
return true
}
}
간단히 설명하면 백스페이스는 \b 의 문자를 가지고 UInt32 의 형태로 변환하면 -92 의 값을 가진다고 합니다. 그래서 들어온 string 값 이 백스페이스 이면 사용자의 값을 실행시킵니다. 백스페이스 처리까지 끝내면 정상적으로 동작합니다.