azhy의 iOS 이야기

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

Swift

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

azhy 2024. 11. 11. 20:15

2022년 6월 5일에 작성됨

 

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