LoginSignup
0
2

UIKitとSwiftUIのViewの描画周りで気をつけること

Posted at

気をつけることと両者の違い

結論から言うと、気をつけるべきことは、クラスの性質構造体の性質に注意するということ。
また、両者の違いは、主にUIkitはクラスでViewが作成され、SwiftUIは構造体でViewが作成されることである。

このトピックにおけるUIKitの性質

  • クラスの生成

    • 通常、クラスで作成したインスタンスは、アプリのライフサイクル内で一度生成されると、(自分でインスタンスを破棄するコードを書くなど以外で)そのインスタンスはほとんど破棄されることはなく保持される。そのため、データや設定が安定して維持される。
  • いつクラスのインスタンスが破棄されるのか?

    • 通常は、ViewController自体が破棄されるときに一緒に破棄される。
      • 破棄されるタイミングの具体例
        • ユーザーが画面上の戻るボタンを押して前の画面に戻ると、現在のビューコントローラーが破棄される。
        • メモリ不足の状況下で、システムがビューコントローラーとそのビューを解放し、メモリを開放することがある。
    • ただし、具体的な破棄タイミングはシステムに依存し、アプリのコードで直接制御することは難しいことが多い。したがって、破棄のタイミングは開発者側は詳しくは分からないことがある。

このトピックにおけるSwiftUIの性質

  • 再描画の度に新しいViewのインスタンスを生成するため、View内でインスタンス(クラスで作成した)を作成する場合、再生成の際に新しいインスタンスが作成される。
    • そのため、以前のデータや設定が失われることがある。
      • @State@Binding、または他のSwiftUIの状態管理メカニズムを使用する。これらにより、再描画時にデータが失われず、正しく動作するアプリを開発できる。
      • 下記ソースコードで確認する。

ソースコード

  • 再描画によってテキスト(データ)が消える実装
Swift
struct ContentView: View {
    // クラスを用いてユーザーのテキスト入力を保持する
    class UserData {
        var userInput = ""
    }

    // UserDataクラスのインスタンス
    // 再描画の度に新しいuserDataインスタンスが生成されるから、前に入力されたユーザーの入力が再描画時に消えてしまう
    @State var userData = UserData()
    var body: some View {
        VStack {
            Text("テキストフィールドに入力したテキスト: \(userData.userInput)")
            TextField("テキストを入力してください", text: $userData.userInput)
        }

    }
}
  • @Stateプロパティーラッパーを使って、状態管理をして、再描画時にもデータが失われないようにする
Swift
struct ContentView: View {
    // ユーザーがテキスト入力をすると、@Stateプロパティによって追跡される
    // その結果、再描画時にも状態が保持され、入力内容も消えない
    @State var userInput = ""

    var body: some View {
        VStack {
            Text("テキストフィールドに入力したテキスト: \(userInput)")
            TextField("テキストを入力してください", text: $userInput)
        }
    }
}

おわりに

間違い等ありましたらコメント欄にてご指摘ください!

参考記事

開発環境

  • Xcode-14.3
  • Swift version 5.8
0
2
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
2