Upgrade to Pro — share decks privately, control downloads, hide ads and more …

EmptyViewは本当に“空”なのか?

Avatar for akkiee76 akkiee76
September 12, 2026

 EmptyViewは本当に“空”なのか?

iOSDC Japan 2026 の登壇資料

『EmptyViewは本当に空なのか?』

https://fortee.jp/iosdc-japan-2026/proposal/accepted?l=e27f87a1-9470-4080-9718-a36e4dd8c2b0

Avatar for akkiee76

akkiee76

September 12, 2026

More Decks by akkiee76

Other Decks in Technology

Transcript

  1. 📃 Documentation Structure EmptyView A view that doesn t contain

    any content Overview ’ EmptyView represents the absence of a view.
  2. 🔍 事件現場 iOSDC Track A の参加者をチェックするアプリ +, − 参加者の増減 ^

    ATTENDEES パネルの表示・非表示 閉じた状態は EmptyView で表現 パネルを開閉すると、 State まで初期化されてしまう 🚨
  3. 🔍 現場検証 struct ContentView: View { @State private var isExpanded

    = true var body: some View { VStack(alignment: .leading, spacing: 24) { // ヘッダーセクション Button { isExpanded.toggle() } label: { Image(systemName: "chevron.up") } if isExpanded { AttendeeCounterView() } else { EmptyView() } } } } struct AttendeeCounterView: View { @State private var count = 0 var body: some View { // カウンターUI } }
  4. 🔍 EmptyView の Public Interface @frozen public struct EmptyView :

    View { @inlinable public init() public typealias Body = Never } 1. 保存プロパティを持たない 2. Body == Never 3. 表示する子 View も持たない EmptyView の中身は、本当に空だった…
  5. 🔍 EmptyView 周辺を再検証 SwiftUI から見えている構造 var body: some View {

    if isSessionExpanded { some View = _ConditionalContent< AttendeeCounterView() AttendeeCounterView, True EmptyView False } else { EmptyView() } } >
  6. 🔍 View Identity SwiftUI が View の同一性を判断するための仕組み • Explicit Identity

    (明示的な識別) • Structural Identity(構造による識別)
  7. 🔍 Structural Identity View の型と、階層構造上の位置から決まる Identity var body: some View

    { // ・・・ if isExpanded { AttendeeCounterView() } else { EmptyView() } } “True” View IDENTITY: A “False” View IDENTITY: B
  8. 🔍 Identity と Lifetime の関係 View Identity の Lifetime →

    State の Lifetime AttendeeCounterView Lifetime IDENTITY: A 開始 count = 0 onAppear count = 1 count = 2 count = 3 IDENTITY: A 終了 onDisappear
  9. 🔍 Explicit Identity 開発者やデータが明示的に与える Identity ScrollViewReader { proxy in HeaderView()

    .id(headerId) ContentView() Button("Scroll to Top") { withAnimation { proxy.scrollTo(headerId) } } }
  10. ✅ State を維持する設計 struct ContentView: View { @State private var

    isExpanded = true @State private var count = 0 var body: some View { VStack(alignment: .leading, spacing: 24) { // ・・・ } } } if isExpanded { AttendeeCounterView(count: $count) } else { EmptyView() } struct AttendeeCounterView: View { @Binding var count: Int var body: some View { // カウンターUI } }
  11. 🔍 まとめ • EmptyView の中身は、本当に空だった • State 消失の鍵は、View Identity と

    Lifetime • 真相は、自分のメンタルモデル 「EmptyView = 存在しない」