@@ -40,7 +40,7 @@ final class WithdrawViewController: BaseViewController<WithdrawViewModel> {
4040 private let withdrawReasonView = UIView ( )
4141 private let withdrawReasonLabel = UILabel ( )
4242 private let withdrawReasonStackView = UIStackView ( )
43- private var withdrawButtons : [ WithdrawReason : BitnagilChoiceButton ] = [ : ]
43+ private var withdrawReasonButtons : [ WithdrawReason : BitnagilChoiceButton ] = [ : ]
4444 private let withdrawReasonTextBackgroundView = UIView ( )
4545 private let withdrawReasonTextViewPlaceholder = UILabel ( )
4646 private let withdrawReasonTextView = UITextView ( )
@@ -63,6 +63,11 @@ final class WithdrawViewController: BaseViewController<WithdrawViewModel> {
6363 }
6464 }
6565
66+ override func viewWillDisappear( _ animated: Bool ) {
67+ super. viewWillDisappear ( animated)
68+ removeKeyboardNotification ( )
69+ }
70+
6671 private func updateConstraint( ) {
6772 let height = view. bounds. height
6873 if height <= 667 {
@@ -121,7 +126,7 @@ final class WithdrawViewController: BaseViewController<WithdrawViewModel> {
121126 make. height. equalTo ( Layout . withdrawChoiceButtonHeight)
122127 }
123128 withdrawReasonStackView. addArrangedSubview ( withdrawChoiceButton)
124- withdrawButtons [ withdrawReason] = withdrawChoiceButton
129+ withdrawReasonButtons [ withdrawReason] = withdrawChoiceButton
125130 }
126131
127132 withdrawReasonTextBackgroundView. backgroundColor = BitnagilColor . gray99
@@ -147,6 +152,12 @@ final class WithdrawViewController: BaseViewController<WithdrawViewModel> {
147152 self ? . viewModel. action ( input: . withdrawService)
148153 } ,
149154 for: . touchUpInside)
155+
156+ let tapGesture = UITapGestureRecognizer ( target: self , action: #selector( dismissKeyboard) )
157+ tapGesture. cancelsTouchesInView = false
158+ view. addGestureRecognizer ( tapGesture)
159+
160+ configureKeyboardNotification ( )
150161 }
151162
152163 override func configureLayout( ) {
@@ -284,7 +295,7 @@ final class WithdrawViewController: BaseViewController<WithdrawViewModel> {
284295 }
285296
286297 private func updateWithdrawReason( selectedWithdrawReason: WithdrawReason ? ) {
287- withdrawButtons . forEach { withdrawReason in
298+ withdrawReasonButtons . forEach { withdrawReason in
288299 let isSelected = withdrawReason. key == selectedWithdrawReason
289300 withdrawReason. value. updateButtonState ( isChecked: isSelected)
290301 }
@@ -296,11 +307,74 @@ final class WithdrawViewController: BaseViewController<WithdrawViewModel> {
296307 withdrawReasonMaxLengthLabel. isHidden = true
297308 }
298309 }
310+
311+ private func configureKeyboardNotification( ) {
312+ NotificationCenter . default. addObserver (
313+ self ,
314+ selector: #selector( keyboardWillAppear) ,
315+ name: UIResponder . keyboardWillShowNotification,
316+ object: nil )
317+
318+ NotificationCenter . default. addObserver (
319+ self ,
320+ selector: #selector( keyboardWillDisappear) ,
321+ name: UIResponder . keyboardWillHideNotification,
322+ object: nil )
323+ }
324+
325+ private func removeKeyboardNotification( ) {
326+ NotificationCenter . default. removeObserver (
327+ self ,
328+ name: UIResponder . keyboardWillShowNotification,
329+ object: nil )
330+
331+ NotificationCenter . default. removeObserver (
332+ self ,
333+ name: UIResponder . keyboardWillHideNotification,
334+ object: nil )
335+ }
336+
337+ @objc private func dismissKeyboard( ) {
338+ view. endEditing ( true )
339+ }
340+
341+ @objc private func keyboardWillAppear( _ sender: Notification ) {
342+ guard
343+ let keyboardFrame = sender. userInfo ? [ UIResponder . keyboardFrameEndUserInfoKey] as? CGRect ,
344+ let duration = sender. userInfo ? [ UIResponder . keyboardAnimationDurationUserInfoKey] as? Double
345+ else { return }
346+
347+ let keyboardHeight = keyboardFrame. height
348+ let buttonFrame = withdrawButton. convert ( withdrawButton. bounds, to: view)
349+ let buttonBottom = buttonFrame. maxY
350+ let visibleHeight = view. frame. height - keyboardHeight
351+
352+ if buttonBottom > visibleHeight {
353+ let offset = buttonBottom - visibleHeight + 50
354+
355+ UIView . animate ( withDuration: duration) {
356+ self . view. frame. origin. y = - offset
357+ }
358+ }
359+ }
360+
361+ @objc private func keyboardWillDisappear( _ sender: Notification ) {
362+ guard let duration = sender. userInfo ? [ UIResponder . keyboardAnimationDurationUserInfoKey] as? Double
363+ else { return }
364+
365+ UIView . animate ( withDuration: duration) {
366+ self . view. frame. origin. y = 0
367+ }
368+ }
299369}
300370
301371extension WithdrawViewController : UITextViewDelegate {
302372 func textViewDidBeginEditing( _ textView: UITextView ) {
303373 viewModel. action ( input: . choiceWithdrawReason( reason: nil ) )
374+
375+ if !textView. text. isEmpty {
376+ viewModel. action ( input: . inputWithdrawReason( reason: textView. text) )
377+ }
304378 }
305379
306380 func textViewDidChange( _ textView: UITextView ) {
0 commit comments