Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Refactoring
- Observable
- uiscrollview
- map
- swiftUI
- SWIFT
- Human interface guide
- Protocol
- swift documentation
- 리펙토링
- UICollectionView
- RxCocoa
- ribs
- clean architecture
- HIG
- 애니메이션
- 클린 코드
- rxswift
- uitableview
- MVVM
- 리팩토링
- combine
- tableView
- Clean Code
- collectionview
- ios
- 스위프트
- UITextView
- 리펙터링
- Xcode
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] UITextField 포맷 (핸드폰 번호, 이메일, 카드 번호) - AnyFormatKit 사용 본문
iOS 응용 (swift)
[iOS - swift] UITextField 포맷 (핸드폰 번호, 이메일, 카드 번호) - AnyFormatKit 사용
jake-kim 2020. 12. 9. 23:36cocoapod
pod 'AnyFormatKit'
구현
- import
import AnyFormatKit
- 델리게이트 함수에 적용
textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
예제1) 폰 번호 포맷 - 010-1234-2134
extension ViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else {
return false
}
let characterSet = CharacterSet(charactersIn: string)
if CharacterSet.decimalDigits.isSuperset(of: characterSet) == false {
return false
}
let formatter = DefaultTextInputFormatter(textPattern: "###-####-####")
let result = formatter.formatInput(currentText: text, range: range, replacementString: string)
textField.text = result.formattedText
let position = textField.position(from: textField.beginningOfDocument, offset: result.caretBeginOffset)!
textField.selectedTextRange = textField.textRange(from: position, to: position)
return false
}
}
* 주의사항
- return false하게 되면, rx를 쓸 경우 textField.rx.text이벤트가 발생하지 않음
- return false를 하게 되어도, 위 델리게이트 함수에서 textField.text에 값을 입력하면 반영 됨
- textField.selectedTextRange를 통해 cursor의 위치를 바꾸어 줌
예제2) 카드 비밀번호 2자리 포맷 - 34**
xtension ViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard var text = textField.text else {
return false
}
let characterSet = CharacterSet(charactersIn: string)
if CharacterSet.decimalDigits.isSuperset(of: characterSet) == false {
return false
}
let newLength = text.count + string.count - range.length
if (range.length == 2 || range.length == 4) && string.isEmpty { // 2개 이상 선택하여 삭제하는 경우
textField.text = ""
return false
}
let formatter = DefaultTextInputFormatter(textPattern: "##**", patternSymbol: "#")
if newLength == 2 {
text += " "
}
let result = formatter.formatInput(currentText: text, range: range, replacementString: string)
textField.text = result.formattedText
let position = textField.position(from: textField.beginningOfDocument, offset: result.caretBeginOffset)!
textField.selectedTextRange = textField.textRange(from: position, to: position)
return false
}
}
활용) 핸드폰 번호 포멧 및 커서 위치 자동 설정 extension (10 ~ 11자리 핸드폰 번호)
extension UITextField {
func formatPhoneNumber(range: NSRange, string: String) {
guard let text = self.text else {
return
}
let characterSet = CharacterSet(charactersIn: string)
if CharacterSet.decimalDigits.isSuperset(of: characterSet) == false {
return
}
let newLength = text.count + string.count - range.length
let formatter: DefaultTextInputFormatter
let onlyPhoneNumber = text.filter { $0.isNumber }
let currentText: String
if newLength < 13 {
if text.count == 13, string.isEmpty { // crash 방지
formatter = DefaultTextInputFormatter(textPattern: "###-####-####")
} else {
formatter = DefaultTextInputFormatter(textPattern: "###-###-####")
}
} else {
formatter = DefaultTextInputFormatter(textPattern: "###-####-####")
}
currentText = formatter.format(onlyPhoneNumber) ?? ""
let result = formatter.formatInput(currentText: currentText, range: range, replacementString: string)
if text.count == 13, string.isEmpty {
self.text = DefaultTextInputFormatter(textPattern: "###-###-####").format(result.formattedText.filter { $0.isNumber })
} else {
self.text = result.formattedText
}
let position: UITextPosition
if self.text?.substring(from: result.caretBeginOffset - 1, to: result.caretBeginOffset - 1) == "-" {
position = self.position(from: self.beginningOfDocument, offset: result.caretBeginOffset + 1)!
} else {
position = self.position(from: self.beginningOfDocument, offset: result.caretBeginOffset)!
}
self.selectedTextRange = self.textRange(from: position, to: position)
}
}
- 사용하는 입장:
extension MyVC: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
textField.formatPhoneNumber(range: range, string: string)
return false
}
}
source code:github.com/JK0369/sampleFormat
'iOS 응용 (swift)' 카테고리의 다른 글
[iOS - swift] 앱을 첫 번째 실행 시, keychain정보를 삭제하는 방법 (0) | 2020.12.17 |
---|---|
[iOS - swift] String에 substring, removeAt, insertAt 구현 (0) | 2020.12.10 |
[iOS - swift] timer 구현 (background에서 다시 foreground로 온 경우에도 적용) (0) | 2020.11.30 |
[iOS - swift] 커스텀 팝업 창 (custom popup, custom alert view) (5) | 2020.11.28 |
[iOS - swift] table view, section으로 cell 그룹화하는 방법, cell 그룹화 (서비스 약관 화면 만들기) (0) | 2020.11.28 |
Comments