要件#
新しいアプリ LinguaTale では、NavigationView のサブビューであるリストビューのカスタムヘッダーを作成したいと思います。このヘッダーでは、画面の上部に画像を設定し、セーフエリアを無視します。最終的には、以下のスクリーンショットに示すようになります。
実装#
.toolbarBackground(.hidden, for: .navigationBar)を使用して、navigationBar のデフォルトの背景を非表示にします。overlay修飾子を使用して、HeaderView を設定します。.background修飾子を使用して、HeaderView に画像の背景を設定します。- 画像の背景修飾子の前に
.background(.ultraThinMaterial.opacity(0.8))を使用して、画像を少しぼかし、画像の上にあるテキストがよりはっきり見えるようにします。 - 背景画像に
.edgesIgnoringSafeArea(.top)を設定して、画面の上部に広がるようにします。 - ScrollView 内に
HeaderView().opacity(0)を設定し、ScrollView 内の最初のビューと同じスペースを占有するようにします。この見えないビューは、overlay内の HeaderView によって ScrollView 内の実際の最初の要素が隠されないようにするために使用されます。 
import SwiftUI
struct DemoView: View {
    var body: some View {
        VStack {
            ScrollView {
                HeaderView()
                    .opacity(0) // この見えないビューはスペースを占有するために使用されます
            }
        }
        .toolbarBackground(.hidden, for: .navigationBar)
        .overlay(alignment: .top) {
            HeaderView()
                .background(.ultraThinMaterial.opacity(0.8))
                .background {
                    Image("TheBackgroundImage")
                        .resizable(resizingMode: .stretch)
                        .edgesIgnoringSafeArea(.top)
                }
        }
    }
}
struct HeaderView: View {
    var body: some View {
        Text("これはデモのヘッダービューです")
    }
}