[iOS] UITextField 글자 수 제한, 백스페이스 처리

ungchun·2022년 6월 5일
2
post-thumbnail

UITextField 를 쓰다보니 글자 수를 제한해야하는 경우가 생겼는데 그 방법을 한번 정리해보려한다.

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 값 이 백스페이스 이면 사용자의 값을 실행시킵니다. 백스페이스 처리까지 끝내면 정상적으로 동작합니다.

0개의 댓글