こんにちは。 SwiftUIで複雑なViewを定義する時は以下のようにSubviewに分けることがあると思います。
例えばよくあるユーザー詳細画面だとすごくざっくりこんな感じになると思います(本当はさらに複雑に分解されると思いますが)
- UserDetailView
- UserDetailHeaderView
- UserDetailContentView
- UserDetailContentSubView
この場合、Subviewの名前が長くなるので僕はよくextension を使って以下のように書きます。
// UserDetailHeaderView.swift extension UserDetailView { struct HeaderView: View { // 略 } } // UserDetailContentView.swift extension UserDetailView { struct ContentView: View { var body: some View { ContentSubView() // 他にもいろいろなView } } } extension UserDetailView { struct ContentSubView { // 略 }
こうすることで UserDetailViewは以下のようにシンプルに保てます。
struct UserDetailView: View { var body: some View { VStack { HeaderView() ContentView() } } }
このような書き方にするとビルドは普通に通るしプレビューもできます。
問題発生
しかしSubviewの方でプレビューを作ると困ったことになります。
例えば UserDetailContentView.swift
でPreviewを表示しようとした場合にはなぜか ContentSubView
が見つからないというエラーが発生するので UserDetailView.ContentSubView
という書き方をしなくてはいけません。
このエラーは extension で囲ったViewから別のextensionで囲ったViewを参照している場合のプレビューの場合だけ発生します。
親View(UserDetailView)でのプレビューや単体でのPreview時には発生しません。
Xcodeのプレビュー問題なのか?そのような書き方がそもそもできないのか?詳しく調べていないのでよくわかりませんがプレビューのときだけ発生して、さらにプレビューのビルドエラーはわかりにくいので共有がてら記事にしてみました。