コンテンツへスキップ

本番コードを変更せずにSwiftUIでローディング状態をプレビューする

SwiftUIプレビューでローディング状態を確認するための、プロダクションコードを変更しないプレビュー専用ヘルパー。

課題

非同期データに依存するビューを構築する場合、通常はスピナーやプレースホルダーを表示するローディング状態があります。プロダクション環境では、ネットワークやデータベースからデータがロードされる間、この状態が短時間表示されます。しかしSwiftUIプレビューでは、モックデータが即座に利用可能なため、ローディング状態が一瞬で過ぎてしまい確認できないか、まったく表示されません。

プレビュー専用の遅延ヘルパー

解決策は、プレビューまたはデバッグコンテキストでのみ人工的な遅延を導入する小さなヘルパーです。パターンは以下の通りです:

struct DelayedStatePreview<Content: View>: View {
   @State private var isLoaded = false
   let delay: Duration
   let content: (Bool) -> Content

   init(
      delay: Duration = .seconds(2),
      @ViewBuilder content: @escaping (Bool) -> Content
   ) {
      self.delay = delay
      self.content = content
   }

   var body: some View {
      content(isLoaded)
         .task {
            try? await Task.sleep(for: delay)
            isLoaded = true
         }
   }
}

プレビューでは以下のように使用します:

#Preview {
   DelayedStatePreview { isLoaded in
      if isLoaded {
         ArticleListView(articles: mockArticles)
      } else {
         LoadingView()
      }
   }
}

Code example showing the preview helper in context

なぜこれが重要なのか

主な利点は、プロダクションコードがクリーンなままであることです。実際のビューに人工的な遅延やデバッグフラグを追加する必要がありません。ヘルパーは純粋にプレビュー層に存在し、ローディング状態の見た目が正しいか、トランジションがスムーズにアニメーションするか、データ到着時にレイアウトがジャンプしないかを視覚的に確認する方法を提供します。

これは、スケルトンローダーやシマーエフェクトを持つビューで特に有用です。ローディング状態の視覚的な品質がユーザー体験の一部となる場面です。

参考になりましたか?BlueskyMastodonでフォローして、Swiftのヒントやインディー開発の最新情報をチェックしてください。