티스토리 뷰

[ios] 친절한 어플리케이션(1) - TextField에서 콤마(,)로 숫자 단위 구분하기


안녕하세요. 현재 제가 진행하고 있는 가상화폐 관련 프로젝트에는 사용자가 구매했던 당시 코인의 가격과 총 얼마치를 구매했는지를 입력하는 TextField들이 있습니다. 물론 TextField를 올리고 사용자가 입력한 데이터를 처리하는 것은 어렵지 않습니다.


하지만 저의 프로젝트에서는 금액을 입력을 해야하기 때문에 조금만 단위가 커져도 ,를 통한 구분이 없기 때문에 액수를 정확히 입력했는지를 확인하기도 어렵고 보기에도 그렇게 좋지는 않습니다.


  • 200000 : 단위 구분이 없는 값
  • 200,000 : 단위 구분을 한 값

오늘은 이렇게 사소해보이지만 사용자에게는 보다 편리함을 제공하는, 즉 친절한 프로그램을 만드는데 필요한 방법 중 하나인 TextField에 값을 입력할 때 자동으로 ,를 넣어주어 자릿수를 구분해주는 법을 알아보도록 하겠습니다.


UITextFieldDelegate

먼저 어느정도 스위프트와 iOS 공부를 하신 분들이라면 이러한 작업은 왠지 관련 프로토콜과 Delegate를 사용해야 할 것 같은데? 라는 생각을 하셨을 것입니다.


맞습니다! 저 또한 그렇게 생각을 했습니다. 하지만 정확히 어떤 행위를 해야할지 몰랐기 때문에 가장 먼저 구글링을 통한 공부였고 여러 소스들을 참고하여 제가 이해할 수 있는 수준으로 직접 이것저것 만져보면서 확인해가며 코드를 작성해보았습니다.


먼저 UITextFieldDelegate를 준수함으로써 우리는 다음의 메소드를 사용할 수 있습니다.


주의깊게 살펴보아야 할 인자는 두 개입니다.


  1. textField : 우리가 사용하게 될 UITextField를 참조하는 변수입니다.
  2. replacementString : 방금 입력한 문자열 값입니다.

이 메소드를 return true만 구현하고 stringtextField.text를 출력하는 코드를 작성 후 프로젝트를 실해하고 값을 입력해보세요. (물론 textField.delegate = self를 해주셔야 합니다.) 생각한 결과가 출력이 되나요?


아닐겁니다. string은 방금 사용자가 입력한 문자열 값이 되고 textField.text의 값은 string이 합쳐지기 전의 문자열입니다. 일반적인 입력에서 string은 사용자가 입력한 문자 하나 하나로 길이가 1인 문자열이 넘어와 입력한 만큼 메소드가 호출되지만 특정 문자열을 복사하고 해당 TextField에 붙여넣기를 하면 string 값은 붙여 넣어진 문자열 전체 값이 됩니다.


그리고 이러한 string과 이전의 문자열을 이용하여 입력된 문자를 해당 문자와 합쳐 입력된 값을 반영할 것인지 아니면 따로 추가적인 작업을 할 것인지, 혹은 반영하지 않을 것인지를 Bool 값을 반환함으로써 이를 알립니다. 즉 false가 반환되면 입력된 값을 이전 문자열에 합치지 않는다는 것이고 (추가적인 작업) , true가 반환되면 입력된 값을 정상적으로 이전의 문자열과 합쳐 반영한다는 것입니다.


저는 이 메소드를 활용해 원하는 기능을 구현할 것입니다.


NumberFormatter

그 다음으로 살펴보아야 할 것은 Formatter입니다. 이 Formatter에서도 저는 NumberFormatter를 사용하여 기존의 값을 원하는 값의 형식(Format)으로 바꿔줄 것입니다. 제가 사용할 포맷은 다음과 같습니다.


  1. 먼저 ,를 통해 숫자를 구분해줄 것이기 때문에 numberStyle.decimal로 설정합니다.

  2. 지역에 따라 .decimal도 차이가 있으니 디바에스에 설정된 지역으로 값을 설정합니다.

  3. 허용할 수 있는 최대 소숫점자리를 설정합니다. 저는 소숫점을 허용하지 않을 것이므로 0으로 설정합니다.

보다 자세한 사항은 다음의 링크를 참조하세요 . Using Number Formatters


Implementation

이제 본격적으로 위의 내용들을 바탕으로 코드를 작성해보도록 하겠습니다.


TextField의 키보드 타입을 NumberPad로 바꿔줍니다.


  • 먼저 사용할 NumberFormatter를 메소드 내부에서 생성하고 설정합니다.

  • 그리고 그 밑에 위와 같은 코드를 작성합니다. 하나씩 살펴보도록 하겠습니다.
  1. 처음 입력하는 것이라면 textField에 값이 존재하지 않겠지만 그것이 아니라면 이미 위의 코드를 통해 ,를 통해 구분된 값들이 존재할 것입니다. 그 값들과 새로 들어온 값 검사한 후 합치기 위해 ,를 제거합니다. 여기서 formatter.groupingSeparator.decimal의 구분점을 의미하고 이를 ""으로 대체한다는 것으로 ,를 제거한다는 의미입니다,

  2. 이렇게 ,가 제거된 문자열과 새로 입력된 문자열을 일단 합칩니다.

  3. 하지만 새로 입력된 값이 숫자가 아닌 값이 들어오면 6번으로 넘어가고 숫자의 형태가 맞다면 블록안으로 들어갑니다.

    • formatter.number(from:)의 인자로 들어간 값이 숫자만으로 이루어진 문자열이면 해당 문자를 숫자로 바꾼 값을 NSNumber의 형태로 반환하지만 그렇지 않으면 nil을 반환합니다.
  4. 입력된 값이 숫자로 이루어진 문자열이 맞다면 위에서 합친 문자열인 beforeFormattedString을 원하는 포맷으로 설정해 놓은 formatterNSNumber의 형태로 바꾼 후 그 값을 다시 String의 형태로 바꿔줍니다.

  5. 그렇게 최종적으로 변환된(,값이 들어간) 값을 textField에 할당합니다. 그리고 이렇게 임의로 값을 바꿔주었기 때문에 false를 반환합니다.

  6. 3번에서 설명한 것과 마찬가지로 새로 입력된 값이 숫자로 이루어진 문자열이 아닌 경우에는 두 가지가 있습니다. 바로 지우는 행위인 백스페이스를 눌렀거나 말 그대로 숫자로 이루어진 문자열이 아닌 경우입니다.

  7. 백스페이스가 입력되면 들어오는 string의 값은 빈 문자열입니다. 즉 백스페이스가 입력되면 맨 마지막의 문자열을 자르고 잘린 문자열의 ,를 앞으로 하나씩 당겨주어야 하기 때문에 다시 포맷 과정을 거쳐 textField에 할당합니다.

    • 문자열을 자르는 코드가 익숙치 않으시다면 제가 작성한 포스팅을 참고해주세요. String 좀 더 알아보기
  8. 만일 숫자가 아닌 다른 입력 값이 들어온다면 입력된 값은 추가되지 않습니다.


마무리

오늘은 이렇게 사소하지만 사용자에게 편리함을 줄 수 있는 기능을 공부해보았습니다. 어쩌면 개발자에게는 귀찮은 작업이 될 수 있으나 그것을 조금만 감수하면 사용자들은 보다 편리하고 직관적으로 어플리케이션을 사용할 수 있으니 항상 이렇게 섬세한 부분까지 신경쓰는 개발을 하도록 노력해야겠습니다. 감사합니다.

 

Source : github


참고자료


  1. Using Number Formatter
  2. [How do you dynamically format a number to have commas in a UITextField entry?


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함