Skip to content

Instantly share code, notes, and snippets.

@erdemildiz
Created March 12, 2026 08:55
Show Gist options
  • Select an option

  • Save erdemildiz/45c5a302441cb93a268ed9b2b7895089 to your computer and use it in GitHub Desktop.

Select an option

Save erdemildiz/45c5a302441cb93a268ed9b2b7895089 to your computer and use it in GitHub Desktop.
UIViewController Lifecycle created by Claude
Display the source blob
Display the rendered blob
Raw
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 1380" width="720" height="1380" font-family="'SF Pro Display', 'Helvetica Neue', Helvetica, Arial, sans-serif">
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0a0a0f"/>
<stop offset="100%" stop-color="#0d0d1a"/>
</linearGradient>
<linearGradient id="initGrad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#1a1a2e"/>
<stop offset="100%" stop-color="#16213e"/>
</linearGradient>
<linearGradient id="loadGrad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#0f3460"/>
<stop offset="100%" stop-color="#1a4a7a"/>
</linearGradient>
<linearGradient id="appearGrad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#065f46"/>
<stop offset="100%" stop-color="#047857"/>
</linearGradient>
<linearGradient id="activeGrad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#1d4ed8"/>
<stop offset="100%" stop-color="#2563eb"/>
</linearGradient>
<linearGradient id="disappearGrad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#92400e"/>
<stop offset="100%" stop-color="#b45309"/>
</linearGradient>
<linearGradient id="deallocGrad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#7f1d1d"/>
<stop offset="100%" stop-color="#991b1b"/>
</linearGradient>
<linearGradient id="memGrad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#581c87"/>
<stop offset="100%" stop-color="#7c3aed"/>
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<filter id="softglow">
<feGaussianBlur stdDeviation="6" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<marker id="arrow" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#4a9eff"/>
</marker>
<marker id="arrowGreen" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#34d399"/>
</marker>
<marker id="arrowOrange" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#fbbf24"/>
</marker>
<marker id="arrowRed" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#f87171"/>
</marker>
<marker id="arrowPurple" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#a78bfa"/>
</marker>
</defs>
<!-- Background -->
<rect width="720" height="1380" fill="url(#bg)"/>
<!-- Subtle grid pattern -->
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#ffffff06" stroke-width="1"/>
</pattern>
<rect width="720" height="1380" fill="url(#grid)"/>
<!-- Title -->
<text x="360" y="50" text-anchor="middle" fill="#ffffff" font-size="22" font-weight="700" letter-spacing="1" filter="url(#glow)">UIViewController Lifecycle</text>
<text x="360" y="74" text-anchor="middle" fill="#4a9eff" font-size="13" letter-spacing="3" font-weight="500">APPLE SWIFT</text>
<line x1="160" y1="84" x2="560" y2="84" stroke="#4a9eff" stroke-width="0.5" opacity="0.4"/>
<!-- ══════════════════════════════════════════ -->
<!-- PHASE LABELS (left side) -->
<!-- ══════════════════════════════════════════ -->
<!-- Initialization Phase Label -->
<rect x="12" y="105" width="8" height="140" rx="4" fill="#3b82f6" opacity="0.6"/>
<text x="8" y="185" text-anchor="middle" fill="#93c5fd" font-size="10" font-weight="600" letter-spacing="2" transform="rotate(-90,8,185)">INIT</text>
<!-- Loading Phase Label -->
<rect x="12" y="285" width="8" height="200" rx="4" fill="#0ea5e9" opacity="0.6"/>
<text x="8" y="390" text-anchor="middle" fill="#7dd3fc" font-size="10" font-weight="600" letter-spacing="2" transform="rotate(-90,8,390)">LOAD</text>
<!-- Appearance Phase Label -->
<rect x="12" y="525" width="8" height="320" rx="4" fill="#10b981" opacity="0.6"/>
<text x="8" y="690" text-anchor="middle" fill="#6ee7b7" font-size="10" font-weight="600" letter-spacing="2" transform="rotate(-90,8,690)">APPEAR</text>
<!-- Layout Phase Label -->
<rect x="12" y="885" width="8" height="120" rx="4" fill="#8b5cf6" opacity="0.6"/>
<text x="8" y="950" text-anchor="middle" fill="#c4b5fd" font-size="10" font-weight="600" letter-spacing="2" transform="rotate(-90,8,950)">LAYOUT</text>
<!-- Disappearance Phase Label -->
<rect x="12" y="1045" width="8" height="200" rx="4" fill="#f59e0b" opacity="0.6"/>
<text x="8" y="1150" text-anchor="middle" fill="#fde68a" font-size="10" font-weight="600" letter-spacing="2" transform="rotate(-90,8,1150)">DISAPPEAR</text>
<!-- Dealloc Phase Label -->
<rect x="12" y="1285" width="8" height="70" rx="4" fill="#ef4444" opacity="0.6"/>
<text x="8" y="1325" text-anchor="middle" fill="#fca5a5" font-size="10" font-weight="600" letter-spacing="2" transform="rotate(-90,8,1325)">DEALLOC</text>
<!-- ══════════════════════════════════════════ -->
<!-- NODES -->
<!-- ══════════════════════════════════════════ -->
<!-- 1. init(coder:) / init(nibName:bundle:) -->
<rect x="100" y="100" width="520" height="68" rx="12" fill="url(#initGrad)" stroke="#3b82f6" stroke-width="1.5" filter="url(#glow)"/>
<rect x="100" y="100" width="4" height="68" rx="2" fill="#3b82f6"/>
<text x="360" y="128" text-anchor="middle" fill="#93c5fd" font-size="11" font-weight="600" letter-spacing="1">INITIALIZATION</text>
<text x="360" y="148" text-anchor="middle" fill="#ffffff" font-size="14" font-weight="700">init(coder:) / init(nibName:bundle:)</text>
<text x="360" y="162" text-anchor="middle" fill="#64748b" font-size="10">Object is created and initialized</text>
<!-- Arrow down -->
<line x1="360" y1="168" x2="360" y2="208" stroke="#4a9eff" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="250" y="176" width="220" height="18" rx="4" fill="#0a0a0f" opacity="0.8"/>
<text x="360" y="188" text-anchor="middle" fill="#4a9eff" font-size="10">View not yet loaded</text>
<!-- 2. loadView() -->
<rect x="100" y="210" width="520" height="60" rx="12" fill="url(#loadGrad)" stroke="#0ea5e9" stroke-width="1.5"/>
<rect x="100" y="210" width="4" height="60" rx="2" fill="#0ea5e9"/>
<text x="360" y="234" text-anchor="middle" fill="#7dd3fc" font-size="11" font-weight="600" letter-spacing="1">① loadView()</text>
<text x="360" y="252" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="600">Creates or loads the view hierarchy</text>
<text x="360" y="264" text-anchor="middle" fill="#64748b" font-size="10">Override to create views programmatically</text>
<!-- Arrow down -->
<line x1="360" y1="270" x2="360" y2="295" stroke="#4a9eff" stroke-width="2" marker-end="url(#arrow)"/>
<!-- 3. viewDidLoad() -->
<rect x="100" y="297" width="520" height="72" rx="12" fill="url(#loadGrad)" stroke="#0ea5e9" stroke-width="2" filter="url(#glow)"/>
<rect x="100" y="297" width="4" height="72" rx="2" fill="#38bdf8"/>
<!-- Star badge -->
<circle cx="610" cy="333" r="14" fill="#38bdf8" opacity="0.2"/>
<text x="610" y="337" text-anchor="middle" fill="#38bdf8" font-size="11">★</text>
<text x="360" y="320" text-anchor="middle" fill="#7dd3fc" font-size="11" font-weight="600" letter-spacing="1">② viewDidLoad()</text>
<text x="360" y="340" text-anchor="middle" fill="#ffffff" font-size="15" font-weight="700">View loaded into memory</text>
<text x="360" y="358" text-anchor="middle" fill="#a0aec0" font-size="10">Called once. Setup IBOutlets, network calls, data init</text>
<!-- Arrow down -->
<line x1="360" y1="369" x2="360" y2="393" stroke="#34d399" stroke-width="2" marker-end="url(#arrowGreen)"/>
<rect x="240" y="376" width="240" height="18" rx="4" fill="#0a0a0f" opacity="0.8"/>
<text x="360" y="388" text-anchor="middle" fill="#34d399" font-size="10">View about to appear on screen</text>
<!-- 4. viewWillAppear(_:) -->
<rect x="100" y="395" width="520" height="64" rx="12" fill="url(#appearGrad)" stroke="#10b981" stroke-width="1.5"/>
<rect x="100" y="395" width="4" height="64" rx="2" fill="#10b981"/>
<text x="360" y="418" text-anchor="middle" fill="#6ee7b7" font-size="11" font-weight="600" letter-spacing="1">③ viewWillAppear(_ animated: Bool)</text>
<text x="360" y="438" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="600">View is about to be added to window</text>
<text x="360" y="452" text-anchor="middle" fill="#64748b" font-size="10">Refresh UI, start animations, update data</text>
<!-- Arrow down -->
<line x1="360" y1="459" x2="360" y2="483" stroke="#34d399" stroke-width="2" marker-end="url(#arrowGreen)"/>
<!-- 5. viewIsAppearing(_:) -->
<rect x="100" y="485" width="520" height="64" rx="12" fill="url(#appearGrad)" stroke="#059669" stroke-width="1.5"/>
<rect x="100" y="485" width="4" height="64" rx="2" fill="#059669"/>
<rect x="580" y="492" width="34" height="16" rx="8" fill="#10b981" opacity="0.25"/>
<text x="597" y="503" text-anchor="middle" fill="#6ee7b7" font-size="8" font-weight="700">iOS 17</text>
<text x="360" y="508" text-anchor="middle" fill="#6ee7b7" font-size="11" font-weight="600" letter-spacing="1">④ viewIsAppearing(_ animated: Bool)</text>
<text x="360" y="528" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="600">View is in the hierarchy &amp; has geometry</text>
<text x="360" y="542" text-anchor="middle" fill="#64748b" font-size="10">Layout/size already applied. Replaces viewWillLayoutSubviews in iOS 17+</text>
<!-- Arrow down -->
<line x1="360" y1="549" x2="360" y2="573" stroke="#34d399" stroke-width="2" marker-end="url(#arrowGreen)"/>
<!-- 6. viewWillLayoutSubviews() -->
<rect x="100" y="575" width="520" height="60" rx="12" fill="url(#memGrad)" stroke="#7c3aed" stroke-width="1.5"/>
<rect x="100" y="575" width="4" height="60" rx="2" fill="#8b5cf6"/>
<text x="360" y="598" text-anchor="middle" fill="#c4b5fd" font-size="11" font-weight="600" letter-spacing="1">⑤ viewWillLayoutSubviews()</text>
<text x="360" y="616" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="600">View bounds are about to change</text>
<text x="360" y="630" text-anchor="middle" fill="#64748b" font-size="10">Called before layoutSubviews on the view</text>
<!-- Arrow down -->
<line x1="360" y1="635" x2="360" y2="659" stroke="#a78bfa" stroke-width="2" marker-end="url(#arrowPurple)"/>
<!-- 6b. layoutSubviews -->
<rect x="180" y="661" width="360" height="40" rx="10" fill="#1e1e3a" stroke="#6d28d9" stroke-width="1" stroke-dasharray="5,3"/>
<text x="360" y="677" text-anchor="middle" fill="#8b5cf6" font-size="10" font-weight="600">view.layoutSubviews()</text>
<text x="360" y="692" text-anchor="middle" fill="#64748b" font-size="9">Auto Layout engine resolves constraints</text>
<!-- Arrow down -->
<line x1="360" y1="701" x2="360" y2="723" stroke="#a78bfa" stroke-width="2" marker-end="url(#arrowPurple)"/>
<!-- 7. viewDidLayoutSubviews() -->
<rect x="100" y="725" width="520" height="60" rx="12" fill="url(#memGrad)" stroke="#7c3aed" stroke-width="1.5"/>
<rect x="100" y="725" width="4" height="60" rx="2" fill="#8b5cf6"/>
<text x="360" y="748" text-anchor="middle" fill="#c4b5fd" font-size="11" font-weight="600" letter-spacing="1">⑥ viewDidLayoutSubviews()</text>
<text x="360" y="766" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="600">View bounds have changed</text>
<text x="360" y="780" text-anchor="middle" fill="#64748b" font-size="10">Subviews now have correct frames — finalize layout</text>
<!-- Layout loop note -->
<path d="M 620 745 Q 680 745 680 700 Q 680 650 620 650" stroke="#6d28d9" stroke-width="1.5" fill="none" stroke-dasharray="4,3" marker-end="url(#arrowPurple)"/>
<rect x="625" y="688" width="70" height="28" rx="6" fill="#1e1e3a"/>
<text x="660" y="700" text-anchor="middle" fill="#a78bfa" font-size="8.5" font-weight="600">may repeat</text>
<text x="660" y="712" text-anchor="middle" fill="#64748b" font-size="8">on resize</text>
<!-- Arrow down -->
<line x1="360" y1="785" x2="360" y2="810" stroke="#34d399" stroke-width="2" marker-end="url(#arrowGreen)"/>
<rect x="250" y="793" width="220" height="18" rx="4" fill="#0a0a0f" opacity="0.8"/>
<text x="360" y="805" text-anchor="middle" fill="#34d399" font-size="10">View fully visible to user</text>
<!-- 8. viewDidAppear(_:) -->
<rect x="100" y="812" width="520" height="64" rx="12" fill="url(#appearGrad)" stroke="#10b981" stroke-width="2" filter="url(#softglow)"/>
<rect x="100" y="812" width="4" height="64" rx="2" fill="#34d399"/>
<text x="360" y="835" text-anchor="middle" fill="#6ee7b7" font-size="11" font-weight="600" letter-spacing="1">⑦ viewDidAppear(_ animated: Bool)</text>
<text x="360" y="855" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="600">View is now visible on screen</text>
<text x="360" y="869" text-anchor="middle" fill="#a0aec0" font-size="10">Start timers, analytics, heavy animations, video playback</text>
<!-- Memory Warning Sidebar -->
<rect x="560" y="870" width="145" height="110" rx="10" fill="#1e0a2e" stroke="#7c3aed" stroke-width="1.5" stroke-dasharray="5,3"/>
<text x="632" y="890" text-anchor="middle" fill="#a78bfa" font-size="9" font-weight="700">⚠ MEMORY WARNING</text>
<line x1="560" y1="896" x2="705" y2="896" stroke="#7c3aed" stroke-width="0.5"/>
<text x="632" y="912" text-anchor="middle" fill="#c4b5fd" font-size="9" font-weight="600">didReceiveMemory</text>
<text x="632" y="924" text-anchor="middle" fill="#c4b5fd" font-size="9" font-weight="600">Warning()</text>
<text x="632" y="942" text-anchor="middle" fill="#64748b" font-size="8">Can happen any time</text>
<text x="632" y="954" text-anchor="middle" fill="#64748b" font-size="8">Free cached data</text>
<text x="632" y="966" text-anchor="middle" fill="#64748b" font-size="8">Purge non-essential</text>
<text x="632" y="978" text-anchor="middle" fill="#64748b" font-size="8">objects from memory</text>
<!-- Arrow down from viewDidAppear -->
<line x1="360" y1="876" x2="360" y2="900" stroke="#fbbf24" stroke-width="2" marker-end="url(#arrowOrange)"/>
<rect x="245" y="883" width="230" height="18" rx="4" fill="#0a0a0f" opacity="0.8"/>
<text x="360" y="895" text-anchor="middle" fill="#fbbf24" font-size="10">User navigates away / view hidden</text>
<!-- 9. viewWillDisappear(_:) -->
<rect x="100" y="902" width="520" height="64" rx="12" fill="url(#disappearGrad)" stroke="#f59e0b" stroke-width="1.5"/>
<rect x="100" y="902" width="4" height="64" rx="2" fill="#f59e0b"/>
<text x="360" y="925" text-anchor="middle" fill="#fde68a" font-size="11" font-weight="600" letter-spacing="1">⑧ viewWillDisappear(_ animated: Bool)</text>
<text x="360" y="945" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="600">View about to be removed from window</text>
<text x="360" y="959" text-anchor="middle" fill="#64748b" font-size="10">Save data, resign first responder, stop timers</text>
<!-- Arrow down -->
<line x1="360" y1="966" x2="360" y2="990" stroke="#fbbf24" stroke-width="2" marker-end="url(#arrowOrange)"/>
<!-- 10. viewDidDisappear(_:) -->
<rect x="100" y="992" width="520" height="64" rx="12" fill="url(#disappearGrad)" stroke="#f59e0b" stroke-width="1.5"/>
<rect x="100" y="992" width="4" height="64" rx="2" fill="#f59e0b"/>
<text x="360" y="1015" text-anchor="middle" fill="#fde68a" font-size="11" font-weight="600" letter-spacing="1">⑨ viewDidDisappear(_ animated: Bool)</text>
<text x="360" y="1035" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="600">View removed from window</text>
<text x="360" y="1049" text-anchor="middle" fill="#64748b" font-size="10">Pause playback, clear heavy resources</text>
<!-- Loop back arrow: viewWillAppear -->
<path d="M 100 1024 Q 40 1024 40 750 Q 40 430 100 430" stroke="#fbbf24" stroke-width="1.8" fill="none" stroke-dasharray="6,3" marker-end="url(#arrowGreen)"/>
<rect x="26" y="698" width="50" height="42" rx="6" fill="#1a120a"/>
<text x="51" y="713" text-anchor="middle" fill="#fbbf24" font-size="8.5" font-weight="700">appear</text>
<text x="51" y="725" text-anchor="middle" fill="#fbbf24" font-size="8.5" font-weight="700">again</text>
<text x="51" y="737" text-anchor="middle" fill="#64748b" font-size="8">(push/pop)</text>
<!-- Arrow down to dealloc -->
<line x1="360" y1="1056" x2="360" y2="1080" stroke="#f87171" stroke-width="2" marker-end="url(#arrowRed)"/>
<rect x="245" y="1063" width="230" height="18" rx="4" fill="#0a0a0f" opacity="0.8"/>
<text x="360" y="1075" text-anchor="middle" fill="#f87171" font-size="10">No more strong references</text>
<!-- 11. deinit -->
<rect x="100" y="1082" width="520" height="64" rx="12" fill="url(#deallocGrad)" stroke="#ef4444" stroke-width="2" filter="url(#glow)"/>
<rect x="100" y="1082" width="4" height="64" rx="2" fill="#ef4444"/>
<text x="360" y="1105" text-anchor="middle" fill="#fca5a5" font-size="11" font-weight="600" letter-spacing="1">⑩ deinit</text>
<text x="360" y="1125" text-anchor="middle" fill="#ffffff" font-size="14" font-weight="700">Object deallocated from memory</text>
<text x="360" y="1142" text-anchor="middle" fill="#a0aec0" font-size="10">ARC releases object — cleanup observers, stop all services</text>
<!-- ══════════════════════════════════════════ -->
<!-- LEGEND -->
<!-- ══════════════════════════════════════════ -->
<rect x="100" y="1165" width="520" height="195" rx="14" fill="#0d0d20" stroke="#1e2040" stroke-width="1"/>
<text x="360" y="1190" text-anchor="middle" fill="#94a3b8" font-size="11" font-weight="700" letter-spacing="2">QUICK REFERENCE</text>
<line x1="120" y1="1198" x2="600" y2="1198" stroke="#1e2040" stroke-width="1"/>
<!-- Legend items -->
<rect x="120" y="1210" width="10" height="10" rx="2" fill="#3b82f6"/>
<text x="138" y="1220" fill="#cbd5e1" font-size="10">init — Object creation (called once)</text>
<rect x="120" y="1228" width="10" height="10" rx="2" fill="#0ea5e9"/>
<text x="138" y="1238" fill="#cbd5e1" font-size="10">viewDidLoad — One-time setup after view loads</text>
<rect x="120" y="1246" width="10" height="10" rx="2" fill="#10b981"/>
<text x="138" y="1256" fill="#cbd5e1" font-size="10">viewWillAppear / viewDidAppear — Each time view shows</text>
<rect x="120" y="1264" width="10" height="10" rx="2" fill="#8b5cf6"/>
<text x="138" y="1274" fill="#cbd5e1" font-size="10">Layout methods — Called on bounds change (may repeat)</text>
<rect x="120" y="1282" width="10" height="10" rx="2" fill="#f59e0b"/>
<text x="138" y="1292" fill="#cbd5e1" font-size="10">viewWillDisappear / viewDidDisappear — Each time hidden</text>
<rect x="120" y="1300" width="10" height="10" rx="2" fill="#ef4444"/>
<text x="138" y="1310" fill="#cbd5e1" font-size="10">deinit — ARC deallocation (called once)</text>
<!-- Dash line note -->
<line x1="400" y1="1213" x2="430" y2="1213" stroke="#6d28d9" stroke-width="1.5" stroke-dasharray="4,3"/>
<text x="438" y="1217" fill="#94a3b8" font-size="9">= system-managed step</text>
<!-- Footer -->
<text x="360" y="1362" text-anchor="middle" fill="#334155" font-size="10">UIKit · iOS / iPadOS · Swift</text>
<text x="360" y="1374" text-anchor="middle" fill="#1e293b" font-size="9">viewWillAppear ↔ viewDidDisappear loop repeats on navigation</text>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment