LoginSignup
0
1

More than 1 year has passed since last update.

SwiftUIで認証コード画面実装

Last updated at Posted at 2022-12-24

概要

認証コードを受け付けるような画面をSwiftUIで実装しようと思います。
1文字入力したら、次のフィールドへフォーカスしたり、backspace押下でフォーカスを一つ戻します。
また、アーキテクチャにはMVVMを使用しています。

環境

Xcode 14.2

実装

まず、UIViewRepresentableを使ってUITextFieldをSwiftUIで扱えるようにします。
updateUIViewを使って、テキストフィールドのフォーカスを制御します。
ざっくり以下の手順を想定してます。

  1. UITextFieldをSwiftUIで扱えるようにする
  2. ViewModelでフォーカス中のフィールド情報を更新する

UIViewRepresentable

注目すべきところは、引数でtag, focusTagを受け取っていることです。
focusTagは現在画面でフォーカスが当たっているフィールドのタグです。
tagfocusTagの値が等しい時にフォーカスを当てます。

struct AuthCodeTextFieldRepresentable: UIViewRepresentable {
  ...
  @Binding var focusTag: Int?

  ...
  private let tag: Int
  ...

  init(
    ...
    focusTag: Binding<Int?>,
    ...
    tag: Int,
    ...
  ) {
    self._focusTag = focusTag
    ...
    self.tag = tag
    ...
  }

  ...
  func updateUIView(_ uiView: BaseUITextField, context: Context) {
      if uiView.tag == focusTag {
          uiView.becomeFirstResponder()
      }
  }
  ...
}

ViewModel

現在フォーカスしているフィールドの情報はViewModelで管理します。
最初はどこにもフォーカスさせないので、nilで初期化しています。
UITextFieldの入力イベントはPassthrouSubjectを使うことで受け取っています。

class HomeViewModel: ObservableObject {
  ...
  @Published var focusTag: Int? = nil
  ...

  ...
  private func subscribeEditingChanged() {
    editingChangedSubject
      .receive(on: DispatchQueue.main)
      .sink { [weak self] _ in
          guard let self = self else { return }

          if self.focusTag == .zero {
              self.focusTag = 1
          } else if self.focusTag == 1 {
              self.focusTag = 2
          } else if self.focusTag == 2 {
              self.focusTag = 3
          } else if self.focusTag == 3 {
              self.focusTag = 4
          } else if self.focusTag == 4 {
              self.focusTag = 5
          }
      }
      .store(in: &cancellables)
  }
  ...
}

ソースコードをこちらに添付します。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1