728x90
SMALL
오늘은 계산기 기능을 구현하면서 자주 맞닥뜨리는 문제 중 하나인 '숫자 입력 자릿수 제한'을 어떻게 깔끔하게 구현하는지에 대해 알아보겠습니다.
무한정 숫자를 입력하면 UI가 깨지거나 예상치 못한 버그가 발생할 수 있기 때문에, 이 기능은 사용자 경험을 위해서라도 꼭 필요하죠.
본 가이드에서는 최대 9자리까지 숫자를 입력하도록 제한하고, 10번째 숫자를 누르면 사용자에게 알림창을 띄워주는 방법을 코드를 통해 자세히 설명해 드릴게요.
문제의 핵심: 어디서 로직을 처리해야 할까?
많은 분들이 기존에 구현된 ViewModel의 유효성 검사 메서드에 이 로직을 추가해야 할지 고민하곤 합니다. 하지만 이 기능은 AddAmountViewController 내에서 직접 처리하는 것이 가장 효율적입니다.
이유는 다음과 같습니다:
- 즉각적인 사용자 피드백: 사용자가 키패드 버튼을 누르는 바로 그 순간에 입력을 검증하고 막아야 합니다. ViewModel을 거치면 불필요한 과정이 추가되어 로직이 복잡해집니다.
- 관심사 분리: ViewController는 사용자 인터페이스(UI)의 입력과 출력을 담당합니다. 키패드 입력 처리는 ViewController의 역할에 가장 잘 부합합니다. 최종적으로 데이터를 저장하기 전 검증하는 ViewModel의 역할과는 다르죠.
Swift 코드 구현하기
AddAmountViewController의 keyPressed(_:) 메서드에 다음 코드를 추가하면 됩니다.
이 메서드는 키패드 버튼이 눌릴 때마다 호출되는 함수입니다.
@objc private func keyPressed(_ sender: UIButton) {
guard let key = sender.title(for: .normal) else { return }
switch key {
case "C":
rawExpression = ""
case "⌫":
if !rawExpression.isEmpty {
rawExpression.removeLast()
}
case "=":
guard !rawExpression.isEmpty else { return }
let result = evaluateExpression(from: rawExpression)
rawExpression = result == 0 ? "" : String(result)
// "완료" 버튼 처리
case NSLocalizedString("done", comment: "Label for Done button"):
guard !rawExpression.isEmpty else {
onAmountSelected?(0)
dismiss(animated: true)
return
}
let result = evaluateExpression(from: rawExpression)
onAmountSelected?(Int(result))
dismiss(animated: true)
default:
// MARK: - ⭐ 숫자 자릿수 제한 로직 추가
// 입력된 키가 숫자인지 확인
if ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."].contains(key) {
// 현재 입력된 문자열에서 숫자만 추출 (연산자는 무시)
let currentNumbers = rawExpression.filter({ "0"..."9" ~= $0 || $0 == "." })
// 숫자의 길이가 9자리 이상이고, 입력된 키가 숫자인 경우
if currentNumbers.count >= 9 && key != "." {
// 경고창 표시 후 입력 무시
showLimitAlert()
return
}
}
rawExpression += key
}
updateDisplay()
}
경고창 띄우는 함수
위 코드에서 호출되는 showLimitAlert() 함수를 별도로 만들어주면 더욱 깔끔합니다.
private func showLimitAlert() {
let title = NSLocalizedString("Alert_Title_Limit_Exceeded", comment: "")
let message = NSLocalizedString("Alert_Message_Digit_Limit", comment: "")
let okButtonText = NSLocalizedString("Alert_Button_OK", comment: "")
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: okButtonText, style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}

728x90
LIST
'Project > ReceiptMind' 카테고리의 다른 글
| 앱스토어 출시 전, 버전(Version)과 빌드(Build) 올바르게 설정하는 방법 (0) | 2025.08.23 |
|---|---|
| 📱 iOS 언어 현지화(Localization) 기본 구현 방법 (1) | 2025.08.11 |
| 🇰🇷 한국에서는 한국어, 그 외 국가에서는 영어로 앱 이름 설정하기iOS 앱 현지화: InfoPlist.strings 활용법 (3) | 2025.08.07 |
| 🧩 추가하면 좋은 기능 요약 (3) | 2025.08.04 |
| 💰 Swift reduce 완전 정복: totalAmount() 메서드로 배우는 누적 합계 계산 (0) | 2025.08.03 |