@@ -59,6 +59,11 @@ final class JoinAgencyVC: BaseVC, ReactorKit.View {
5959 }
6060 }
6161
62+ override func viewDidAppear( _ animated: Bool ) {
63+ super. viewDidAppear ( animated)
64+ codeviews [ 0 ] . numberTextField. becomeFirstResponder ( )
65+ }
66+
6267 func bind( reactor: JoinAgencyReactor ) {
6368 setRightItem ( . closeBlack)
6469
@@ -74,45 +79,18 @@ final class JoinAgencyVC: BaseVC, ReactorKit.View {
7479 . disposed ( by: disposeBag)
7580
7681 codeviews. enumerated ( ) . forEach { index, codeView in
77- codeView. numberTextField. rx. text
78- . orEmpty. skip ( 1 )
79- . map { Reactor . Action. textFieldDidChange ( text: $0, index: index) }
80- . bind ( to: reactor. action)
81- . disposed ( by: disposeBag)
82- }
83-
84- codeviews. indices. forEach { index in
85- reactor. pulse ( \. $codes)
86- . map { $0 [ index] }
87- . distinctUntilChanged ( )
88- . observe ( on: MainScheduler . instance)
89- . bind ( with: self ) { owner, code in
90- owner. codeviews [ index] . numberTextField. text = code
91-
92- if code. isEmpty {
93- owner. codeviews [ index] . setState ( . plain)
94- } else {
95- DispatchQueue . main. asyncAfter ( deadline: . now( ) + 0.1 ) {
96- owner. codeviews [ index] . setState ( . done)
97- owner. codeviews [ safe: index+ 1 ] ? . setState ( . focused)
98-
99- if !owner. codeviews. indices. contains ( index+ 1 ) {
100- owner. view. endEditing ( true )
101- }
102- }
103- }
104- }
105- . disposed ( by: disposeBag)
82+ codeView. delegate = self
10683 }
10784
10885 reactor. pulse ( \. $codes)
10986 . distinctUntilChanged ( )
11087 . filter { $0. joined ( ) . count == 6 }
11188 . delay ( . seconds( 1 ) , scheduler: MainScheduler . instance)
89+ . do { [ weak self] _ in self ? . view. endEditing ( true ) }
11290 . map { _ in Reactor . Action. requestJoinAgency}
11391 . bind ( to: reactor. action)
11492 . disposed ( by: disposeBag)
115-
93+
11694 reactor. pulse ( \. $snackBarMessage)
11795 . compactMap { $0 }
11896 . observe ( on: MainScheduler . instance)
@@ -121,10 +99,15 @@ final class JoinAgencyVC: BaseVC, ReactorKit.View {
12199
122100 SnackBarManager . show ( title: message) {
123101 owner. reactor? . action. onNext ( . tapRetryButton)
102+ owner. codeviews. enumerated ( ) . forEach { index, codeView in
103+ codeView. numberTextField. text = " "
104+ codeView. setState ( index == 0 ? . focused : . plain)
105+ }
106+ owner. codeviews [ 0 ] . numberTextField. becomeFirstResponder ( )
124107 }
125108 }
126109 . disposed ( by: disposeBag)
127-
110+
128111 reactor. pulse ( \. $errorMessage)
129112 . compactMap { $0 }
130113 . observe ( on: MainScheduler . instance)
@@ -146,3 +129,71 @@ final class JoinAgencyVC: BaseVC, ReactorKit.View {
146129 . disposed ( by: disposeBag)
147130 }
148131}
132+
133+ extension JoinAgencyVC : UITextFieldDelegate {
134+ func textFieldDidBeginEditing( _ textField: UITextField ) {
135+ textField. selectedTextRange = nil
136+ }
137+
138+ func textField(
139+ _ textField: UITextField ,
140+ shouldChangeCharactersIn range: NSRange ,
141+ replacementString string: String
142+ ) -> Bool {
143+ guard Int ( string) != nil else { return false }
144+ guard let idx = codeviews. map ( \. numberTextField) . firstIndex ( of: textField) else { return false }
145+
146+ if let text = textField. text, !text. isEmpty, !string. isEmpty {
147+ guard idx < codeviews. count - 1 else { return false }
148+ codeviews [ idx+ 1 ] . numberTextField. becomeFirstResponder ( )
149+ codeviews [ idx+ 1 ] . numberTextField. text = string
150+ reactor? . action. onNext ( . textFieldDidChange( text: string, index: idx+ 1 ) )
151+ codeviews [ idx+ 1 ] . setState ( . done)
152+ if idx < codeviews. count - 2 {
153+ codeviews [ idx+ 2 ] . setState ( . focused)
154+ }
155+ return false
156+ }
157+
158+ if string. isEmpty {
159+ textField. text = " "
160+ reactor? . action. onNext ( . textFieldDidChange( text: " " , index: idx) )
161+ codeviews. forEach {
162+ if $0. state == . focused {
163+ $0. setState ( . plain)
164+ }
165+ }
166+ codeviews [ idx] . setState ( . focused)
167+
168+ if idx > 0 {
169+ let prevField = codeviews [ idx- 1 ] . numberTextField
170+ prevField. becomeFirstResponder ( )
171+ prevField. selectedTextRange = prevField. textRange ( from: prevField. endOfDocument, to: prevField. endOfDocument)
172+ }
173+ return false
174+ } else if string. count > 1 {
175+ let numbers = string. compactMap { $0. isNumber ? String ( $0) : nil }
176+ guard !numbers. isEmpty else { return false }
177+
178+ for (index, number) in numbers. prefix ( 6 ) . enumerated ( ) {
179+ let codeview = codeviews [ index]
180+ codeview. numberTextField. text = number
181+ reactor? . action. onNext ( . textFieldDidChange( text: number, index: index) )
182+ codeview. setState ( . done)
183+ }
184+
185+ let nextIndex = min ( codeviews. count - 1 , idx + numbers. count)
186+ let lastTextField = codeviews [ nextIndex] . numberTextField
187+ lastTextField. becomeFirstResponder ( )
188+ lastTextField. selectedTextRange = lastTextField. textRange ( from: lastTextField. endOfDocument, to: lastTextField. endOfDocument)
189+ return false
190+ }
191+
192+ codeviews [ idx] . setState ( . done)
193+ if idx < codeviews. count - 1 {
194+ codeviews [ idx+ 1 ] . setState ( . focused)
195+ }
196+ reactor? . action. onNext ( . textFieldDidChange( text: string, index: idx) )
197+ return true
198+ }
199+ }
0 commit comments