<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Captain SwiftUI]]></title><description><![CDATA[The Captain’s Blog on Swift, SwiftUI, and Apple Development]]></description><link>https://captainswiftui.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!UfAo!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8286878c-57d6-4111-91db-130ef77204be_500x500.png</url><title>Captain SwiftUI</title><link>https://captainswiftui.substack.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 24 Apr 2026 05:18:29 GMT</lastBuildDate><atom:link href="https://captainswiftui.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[DB Technology Services, LLC]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[captainswiftui@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[captainswiftui@substack.com]]></itunes:email><itunes:name><![CDATA[Danny Bolella]]></itunes:name></itunes:owner><itunes:author><![CDATA[Danny Bolella]]></itunes:author><googleplay:owner><![CDATA[captainswiftui@substack.com]]></googleplay:owner><googleplay:email><![CDATA[captainswiftui@substack.com]]></googleplay:email><googleplay:author><![CDATA[Danny Bolella]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Talking Liquid Glass with Apple]]></title><description><![CDATA[I spent three days talking Liquid Glass with Apple in NYC. Here&#8217;s what you need to know.]]></description><link>https://captainswiftui.substack.com/p/talking-liquid-glass-with-apple</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/talking-liquid-glass-with-apple</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Mon, 23 Mar 2026 12:42:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zlyj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zlyj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zlyj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zlyj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zlyj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zlyj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zlyj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:996971,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/191721878?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zlyj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zlyj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zlyj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zlyj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068b758f-bd5d-476a-9639-b66499abd468_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you were developing for Apple platforms a decade ago, you probably remember the WWDC era in San Francisco. The massive scale, the live sessions, the sheer energy of thousands of developers packed into the Moscone Center&#8212;it was an incredible spectacle. But let&#8217;s be honest about the reality of the labs back then: you reserved a time slot, waited around while others got their questions answered, and grabbed whatever brief 1:1 time you could. It was grandiose, and information was largely being fed <em>to</em> you. It was rarely ever &#8220;intimate.&#8221;</p><p>Today, WWDC has evolved into a polished, pre-recorded cinematic event. While you <em>can</em> still go to Apple Park to meet with engineers, the loss of the week-long, in-person conference makes it a tough sell. For many companies and developers, it is incredibly hard to justify the investment of flying out just for a brief lab session.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>But Apple has quietly built something else&#8212;something much more valuable for day-to-day engineering.</p><p>Recently, I had the privilege of attending the &#8220;Let&#8217;s talk Liquid Glass: New design workshop&#8221; at Apple&#8217;s offices in NYC. For three days, from 9 AM to 5 PM, I sat in a highly intimate room with Apple&#8217;s Developer Relations and Design Evangelists team. These were the folks tasked with knowing <em>everything</em> about Liquid Glass so they can travel the globe and help developers and designers actually use it (including one framework engineer in the room who specifically worked on SwiftUI).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wBED!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wBED!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic 424w, https://substackcdn.com/image/fetch/$s_!wBED!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic 848w, https://substackcdn.com/image/fetch/$s_!wBED!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic 1272w, https://substackcdn.com/image/fetch/$s_!wBED!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wBED!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic" width="320" height="568.7912087912088" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6895eca5-c959-4352-a124-9083049f7e1e.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2588,&quot;width&quot;:1456,&quot;resizeWidth&quot;:320,&quot;bytes&quot;:1430011,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/191721878?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wBED!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic 424w, https://substackcdn.com/image/fetch/$s_!wBED!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic 848w, https://substackcdn.com/image/fetch/$s_!wBED!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic 1272w, https://substackcdn.com/image/fetch/$s_!wBED!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6895eca5-c959-4352-a124-9083049f7e1e.heic 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The Captain and Curt Clifton. The fanboying was real those three days.</figcaption></figure></div><p>They were incredibly accessible. I asked every question I could think of, got immediate feedback on lots of ideas and decisions, and worked through real-world implementation challenges for hours on end. It was the peak developer experience I had always hoped the old WWDC labs would be.</p><p>While I was there representing my team and can&#8217;t discuss the specific project details we worked on, there were certain philosophies and strategic insights I walked away with that absolutely apply to every single one of us.</p><p>Here are the universal lessons I learned from Apple&#8217;s Liquid Glass vanguard.</p><h2><strong>Universal Lesson 1: The Ship Has Sailed (Liquid Glass is Permanent)</strong></h2><p>Let&#8217;s address the elephant in the room. If you read the comments on my articles or browse the iOS subreddits, there is a vocal contingent of developers betting that Apple is going to roll back Liquid Glass.</p><p>The rationale usually points to the initial community backlash, the slower adoption rate of iOS 26, and the news that Alan Dye left Apple for Meta. The prevailing theory has been: <em>&#8220;Just wait it out. They&#8217;ll revert to flat design.&#8221;</em></p><p>I shared this exact sentiment with the Apple team.</p><p>Their reaction? Genuine shock. They were actually concerned that developers were holding onto this position. They made it emphatically clear that Liquid Glass is absolutely moving forward, evolving, and expanding across the ecosystem.</p><p>Their exact warning to me was that those who don&#8217;t adopt it now <strong>&#8220;are gonna find themselves in a tough position later.&#8221;</strong></p><p>During the workshop, they admitted they have seen teams who are only interested in doing the bare minimum&#8212;just enough to keep their app from breaking when the new system is forced on. While that is technically allowed, it is a dangerous game of technical debt.</p><p>We had them confirm the hard truth: Xcode 27 will absolutely not have the deferral flag, and it will not respect it if you leave it there, anyway. When Q1 2027 rolls around and Xcode 27 becomes the mandatory minimum for compiling to the App Store, glass will be enabled globally, period.</p><p>If you are waiting for a rollback, you are charting a course for a shipwreck. It&#8217;s time to accept and get into the new system.</p><h2><strong>Universal Lesson 2: Hierarchy is the Anchor (Content is King, Controls are Servants)</strong></h2><p>If you read my previous article, <em><a href="https://captainswiftui.substack.com/p/the-northern-stars-of-liquid-glass">The Northern Stars of Liquid Glass</a></em>, you know the Apple <a href="https://developer.apple.com/design/human-interface-guidelines/">HIG</a> dictates three core design principles for this new era: hierarchy, harmony, and consistency.</p><p>But if you want to know what Apple <em>really</em> cares about people focusing on? It&#8217;s hierarchy.</p><p>Hierarchy wasn&#8217;t just a bullet point; it was the absolute anchor for the entire three-day session. The Apple designers relentlessly emphasized the need to strictly break every screen down into two distinct dimensions: the <strong>content layer</strong> and the <strong>control layer</strong>.</p><p>Here is the harsh truth that many developers (and designers) struggle to accept: nobody opens your app to admire your custom buttons. They open it for the content. Because the content is the ultimate destination, it should be given as much screen real-estate as physically possible.</p><p>To achieve this, your control layer needs to get out of the way. Apple stressed pushing controls to &#8220;prime real-estate&#8221; locations&#8212;specifically the vertical extremes of the screen, like the top navigation bar and/or the bottom toolbar and TabView.</p><p>The rule of thumb they drove home applies across every single Apple platform: <strong>Controls serve the content.</strong></p><p>If a UI element sits in one of those prime locations, its sole purpose must be to facilitate the user&#8217;s interaction with the bedrock content in the center of the screen. If it doesn&#8217;t serve the content, it&#8217;s just visual clutter taking up valuable space.</p><p>I plan to share an article soon where I break down the exact physics, z-axis rules, and &#8220;Barbell Layouts&#8221; of this hierarchy. But the high-level takeaway from the NYC labs is crystal clear: maximize your content, push your controls to the poles, and never let the interface compete with the information.</p><h2><strong>Universal Lesson 3: The Great Reset (and the Promise of WWDC26)</strong></h2><p>I have seen the comments on my posts, and I&#8217;ve read the threads on Reddit and developer forums. There is a lot of frustration out there about the loss of customizable properties and missing sub-elements in some of the new Liquid Glass components. You feel like your toolkit shrank overnight.</p><p>I brought this up directly with the Apple team. The good news? They are completely aware of it.</p><p>They explained that what we are experiencing right now is the exact same phenomenon that happened during the last massive design shift: the move to iOS 7. We just spent over a decade building on a design system that had time to fully evolve and mature from iOS 7 all the way through iOS 18. We had every modifier and customization hook we could ever want.</p><p>Now, we are living through a reset. We are back at Version 1.0.</p><p>The Apple engineers explained that a massive part of the initial Liquid Glass rollout was simply ensuring the foundation was solid. It had to be functional, it had to meet incredibly strict styling guidelines across every single Apple platform, and most importantly, it just had to <em>work</em>. When you are rebuilding the visual physics of an entire OS ecosystem, deep component customization takes a back seat to foundational stability.</p><p>But here is where it gets exciting.</p><p>The team was visibly enthusiastic about what is in store for WWDC26 and Xcode 27. While they wouldn&#8217;t drop any specific spoilers, they gave the very strong impression that this upcoming cycle is where Liquid Glass takes its first massive step into maturity.</p><p>Seeing their level of historical awareness regarding the iOS 7 transition&#8212;and their genuine excitement for what&#8217;s next&#8212;left me incredibly optimistic. The foundation is poured; now, they are getting ready to decorate the house.</p><h2><strong>Universal Lesson 4: Stop Fighting the Framework (SwiftUI Best Practices)</strong></h2><p>Beyond the overarching design principles of Liquid Glass, the Apple engineers dropped some incredibly practical, day-to-day SwiftUI advice. If you want to build robust, modern apps, here are three architectural course corrections straight from the source:</p><p><strong>1. The </strong><code>List</code><strong> vs. </strong><code>ScrollView</code><strong> Reality Check -</strong> Many of us have been defaulting to <code>List</code> the second we need a scrolling column of data. The team made a point to clarify that <code>List</code> should really be reserved for highly specific, uniform data structures, or when you absolutely need built-in swipe actions. For almost everything else? You should be reaching for a <code>ScrollView</code> paired with a <code>LazyVStack</code> or <code>LazyHStack</code>. Between the massive improvements to <code>ScrollView</code> over the last few years and the inherent flexibility and performance of Lazy Stacks, rolling your own scrolling layout gives you far greater control over your styling&#8212;which is helpful when trying to nail the Liquid Glass look.</p><p><strong>2. The Untapped Power of Custom Containers -</strong> They gently reminded us that we have the API to create our own custom containers in SwiftUI. Honestly, this felt like a massive missed opportunity for the community. It is a topic I rarely see covered by other iOS writers or utilized in the open-source repos I review. Instead of hacking a generic <code>VStack</code> with a dozen modifiers to act like a specific container, take the time to build a custom one. It makes your call sites significantly cleaner and your intent much clearer.</p><p><strong>3. Ride the Native Wave (and Style It) -</strong> Especially now, while the maturity of the design system has been &#8220;reset,&#8221; the absolute best thing you can do is stick to native components. If you build a completely custom button or toggle from scratch using raw shapes, your app could get stuck in the past when Apple inevitably rolls out the next waves of Liquid Glass enhancements. Sticking with native components ensures your app naturally rides along with the OS&#8217;s evolution.</p><p>They took it a step further: when you need varying forms of a component, do not rebuild it. <strong>That is exactly what Styles are for.</strong> I touched on this heavily in my recent article on FULL DISCLOSUREgroup, and hearing Apple echo this sentiment validated that approach. Keep the native structural integrity and functional purpose, and use the <code>Style</code> protocols to paint the glass.</p><h2><strong>The Call to Action: Get in the Room</strong></h2><p>Attending WWDC 2016 in San Francisco was a milestone in my career, but spending three days in a quiet room with Apple&#8217;s design evangelists and framework engineers was entirely different. It wasn&#8217;t a spectacle; it was about the craft.</p><p>It is incredibly easy to sit behind our keyboards, read documentation, and complain online when an API doesn&#8217;t work exactly the way we want it to. But when you have 9-to-5 access to the team whose entire job is to know this system inside and out, you realize they are deeply passionate about this platform, they hear our feedback, and they are building for a multi-year horizon.</p><p>If you ever get the opportunity to attend one of these Liquid Glass or similar sessions&#8212;whether it&#8217;s in NYC, Cupertino, London, Tokyo, or elsewhere&#8212;<strong>go.</strong></p><p>With the traditional week-long WWDC conference gone, these localized workshops are the absolute best way to get face-to-face time with Apple. Keep a close eye on the Apple Developer app and website for upcoming design labs. Pitch your company on the ROI of sending you to attend these sessions. The ability to bring your actual codebase, sit down with Apple for three full days, and get unscripted, immediate feedback is unparalleled. It will make you a better engineer, and it will give you a profound understanding of where the wind is blowing in the ecosystem.</p><p>And just in case you need to read it one more time: Liquid Glass is here. It&#8217;s time to learn how to sail it.</p><div><hr></div><p><strong>Navigate the Liquid Glass Transition with The Captain</strong></p><p>The Xcode 27 deadline is approaching, and as the Apple engineers confirmed, there is no deferral flag. You don&#8217;t have to figure out this design reset alone. I have spent most of the last year leading Liquid Glass adoptions, and after my recent three-day intensive at the Apple Developer Center in NYC, I am offering expert-level, 1-on-1 consulting to get your app&#8217;s architecture ready for the new era.</p><p>Whether you need a UI/UX conflict teardown, custom container strategies, or a session to fix your control/content hierarchy, we can map it out.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://docs.google.com/forms/d/e/1FAIpQLSfrc-k6ezeR5aFVJ2RUi_r5n_XWBDjVidu7d78ycVsHOlCwGg/viewform?usp=sharing&quot;,&quot;text&quot;:&quot;Submit an Inquiry!&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://docs.google.com/forms/d/e/1FAIpQLSfrc-k6ezeR5aFVJ2RUi_r5n_XWBDjVidu7d78ycVsHOlCwGg/viewform?usp=sharing"><span>Submit an Inquiry!</span></a></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Objectively Better, Observably Trickier]]></title><description><![CDATA[The Observation Framework is great... once you figure out how it actually works]]></description><link>https://captainswiftui.substack.com/p/objectively-better-observably-trickier</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/objectively-better-observably-trickier</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Wed, 04 Feb 2026 16:31:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!EK1p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EK1p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EK1p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EK1p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EK1p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EK1p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EK1p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1822757,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/185633389?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EK1p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EK1p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EK1p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EK1p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e532c11-2efd-44c1-a6f1-4abf4e02ddba_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let&#8217;s be honest: the <a href="https://developer.apple.com/documentation/observation">Observation Framework</a> and <code>@Observable</code> macro isn&#8217;t brand new. It has been navigating our waters for a few years now, offering a concurrency-safe upgrade to the older, more mysterious <code>ObservableObject</code>. But while many of us have been slowly adopting it, others have clung to the familiar comforts of Combine and <code>@Published</code>.</p><p>However, the recent release of <strong>Xcode 26.3</strong> made the situation crystal clear.</p><p>With the new update, Apple introduced built-in &#8220;Agentic Coding&#8221; and an exposed Model Context Protocol (MCP) to drive it. Curious developers quickly <a href="https://github.com/artemnovichkov/xcode-26-system-prompts">cracked open the internal system prompts</a> that guide Apple&#8217;s own AI assistant. Hidden inside the <a href="https://github.com/artemnovichkov/xcode-26-system-prompts/blob/main/AgentSystemPromptAddition.idechatprompttemplate">AgentSystemPromptAddition</a> was this directive:</p><blockquote><p><strong>&#8220;- Architecture: Follow SwiftUI patterns with clear separation of concerns. Avoid using the Combine framework and instead prefer to use Swift&#8217;s async and await versions of APIs instead.&#8221;</strong></p></blockquote><p>There is no ambiguity left. Apple is explicitly instructing its own intelligence to &#8220;Avoid the Combine framework.&#8221; The era of Combine in SwiftUI is officially coming to a close. We are even seeing the Observation framework mature further with recent enhancements like the <code>Observations</code> type, giving us even more granular control.</p><p><strong>But here is the catch:</strong> If you treat Observation like a simple find-and-replace for Combine, you are going to crash.</p><p>You delete your <code>@Published</code> wrappers, the compiler applauds, but then you tap a button and the UI doesn&#8217;t flinch. You aren&#8217;t crazy, and the API isn&#8217;t broken. You are just experiencing the friction of a fundamental paradigm shift.</p><p>We have moved from a <strong>Push</strong> model (where objects shout &#8220;I changed!&#8221; to anyone listening) to a <strong>Pull</strong> model (where Views quietly and efficiently track <em>only</em> what they touch). It is a smarter, leaner way to build apps, but it requires us to embrace a new mental model.</p><p>So, let&#8217;s clear the fog. Here are a few tips and tricks to help navigate the transition, avoid the common traps, and fully unlock the power of the new observation engine.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>1. The &#8220;Lazy Init&#8221; Trap: Your View is Leaking Performance</h2><p>In the &#8220;Old World,&#8221; <code>@StateObject</code> was our magic shield. It used an <code>@autoclosure</code> to ensure your ViewModel was only instantiated once, effectively acting lazily.</p><p>In the &#8220;New World,&#8221; Apple tells us to use <code>@State</code> to hold our reference types.</p><pre><code><code>// The New Way (Potential Trap)
@State private var viewModel = HeavyViewModel()
</code></code></pre><p>Here lies the trap. Because <code>State</code> does <strong>not</strong> use an autoclosure for its initial value, the Swift runtime executes <code>HeavyViewModel()</code> <strong>every single time</strong> the parent view&#8217;s <code>body</code> is recomputed.</p><p>Yes, SwiftUI is smart enough to discard the <em>new</em> instance and keep using the <em>old</em> one. But the damage is done:</p><ol><li><p><strong>CPU Waste:</strong> You are allocating and deallocating a class instance on every frame refresh.</p></li><li><p><strong>Side Effect Hazards:</strong> If your <code>init()</code> fires off a network request or heavy setup, your app will stutter or trigger duplicate logic.</p></li></ol><h3><strong>The Fix: Defer Creation with </strong><code>.task</code></h3><p>Since we don&#8217;t have a <code>State(lazy:)</code> option, Apple&#8217;s official guidance is to make the state optional and hydrate it using the <code>.task</code> modifier.</p><pre><code><code>struct ContentView: View {
    @State private var viewModel: HeavyViewModel?

    var body: some View {
        HomeView(model: viewModel)
            .task {
                // Only runs once when the view first appears
                if viewModel == nil {
                    viewModel = HeavyViewModel()
                }
            }
    }
}
</code></code></pre><p><strong>Why </strong><code>.task</code><strong>?</strong> It runs immediately before the view appears and, unlike <code>onAppear</code>, automatically handles the lifecycle of any async work if you decide to load data during initialization.</p><div><hr></div><h2>2. The &#8220;Nested Observable&#8221; Dead Zone</h2><p>This is where 90% of developers get stuck. They migrate their code, the compiler is happy, but the UI simply stops updating.</p><p><strong>The Pitfall:</strong></p><p>You have a parent model containing a child model, both marked with <code>@Observable</code>.</p><pre><code><code>@Observable class User {
    var settings = Settings() 
}

@Observable class Settings {
    var isDarkMode = false
}
</code></code></pre><p>If you access <code>user.settings.isDarkMode</code> inside a view that only explicitly observes <code>user</code>, you might miss updates. If you pass <code>user</code> to a child view, and that child view only reads <code>user.settings</code> (the reference), the parent view has <strong>no idea</strong> that the internal properties of <code>settings</code> changed.</p><h3><strong>The Fix: Granular Access or </strong><code>@Bindable</code></h3><p>You must ensure that the specific View that needs to update is the one reading the specific property.</p><p><strong>The Trap (Lazy Observation)</strong></p><pre><code><code>struct UserProfile: View {
    @State var user = User()

    var body: some View {
        VStack {
            // Potential Issue: We are digging deep into the graph.
            // If 'isDarkMode' changes, does UserProfile need to redraw? 
            // It relies on implicit tracking that can be fragile in complex views.
            Toggle("Dark Mode", isOn: Bindable(user.settings).isDarkMode) 
        }
    }
}
</code></code></pre><p><strong>The Solution (Granular Passing)</strong></p><p>Pass the specific node of the graph to the view that needs it. This ensures the &#8220;Spotlight&#8221; is shining exactly where the data changes.</p><pre><code><code>struct UserProfile: View {
    @State var user = User()

    var body: some View {
        VStack {
            Text("User: \(user.name)")
            // FIX: Pass ONLY the child object to a dedicated view.
            SettingsEditor(settings: user.settings)
        }
    }
}

struct SettingsEditor: View {
    // 1. We accept the Observable class instance directly
    @Bindable var settings: Settings

    var body: some View {
        // 2. We bind directly to the property on this scoped object.
        // When 'isDarkMode' changes, ONLY 'SettingsEditor' redraws.
        Toggle("Dark Mode", isOn: $settings.isDarkMode)
    }
}
</code></code></pre><div><hr></div><h2>3. The &#8220;Array Mutation&#8221; Ghost</h2><p>You have a list of items, you toggle a property on one of them, and&#8230; nothing happens.</p><p><strong>The &#8220;Old World&#8221; Habit:</strong></p><p>We used to rely on <code>List($viewModel.items)</code> to get bindings. In the <code>@Observable</code> world, if you try to iterate and bind, you hit a syntax wall because the iterator gives you a <code>let</code> constant, not a binding.</p><pre><code><code>List(viewModel.items) { item in
    // ERROR: Cannot find '$item' in scope
    Toggle(item.title, isOn: $item.isDone) 
}
</code></code></pre><h3><strong>The Fix: Shadowing with </strong><code>@Bindable</code></h3><p>This is the new &#8220;magic spell&#8221; you need to memorize. You must create a <code>@Bindable</code> shadow variable <em>inside</em> the scope where you need the binding.</p><pre><code><code>List(viewModel.items) { item in
    // 1. Create a bindable shadow copy
    @Bindable var item = item
    
    // 2. Now you can access the projected value ($)
    Toggle(item.title, isOn: $item.isDone)
}
</code></code></pre><p>The <code>@Bindable</code> property wrapper creates a bridge. It tells SwiftUI: &#8220;I know this object (<code>item</code>) is <code>@Observable</code>. Please create dynamic bindings for its properties right here, right now.&#8221;</p><p>This isn't just a hack; it is the official pattern prescribed by Apple. As noted in the <a href="https://www.google.com/search?q=%5Bhttps://developer.apple.com/documentation/swiftui/bindable%5D(https://developer.apple.com/documentation/swiftui/bindable)">documentation for </a><code>Bindable</code>, you must create a bindable value within the view's scope to generate bindings for an observable object that you don't own (like one passed into a closure).</p><div><hr></div><h2>4. The &#8220;Computed Property&#8221; Compiler Error</h2><p>You have a favorite property wrapper&#8212;maybe <code>@AppStorage</code>&#8212;and you drop it into your new <code>@Observable</code> class.</p><pre><code><code>@Observable class GameScore {
    // ERROR: Property wrapper cannot be applied to a computed property
    @AppStorage("highScore") var score: Int = 0
}
</code></code></pre><p>This fails because <code>@Observable</code> converts all stored properties into computed properties behind the scenes to inject its tracking logic. Property wrappers generally don&#8217;t like wrapping computed properties.</p><h3><strong>The Captain&#8217;s Advice: The Service Pattern</strong></h3><p>You <em>can</em> fix this by writing complex boilerplate involving <code>@ObservationIgnored</code> (check out <a href="https://github.com/davidsteppenbeck/ObservableUserDefault">this solution</a> by David Steppenbeck and how it works inside). But if you find yourself fighting the compiler to keep <code>@AppStorage</code> inside your observable class, pause for a moment.</p><p>Perhaps it&#8217;s worth considering that you may need to let go of the wrapper convenience and go back to more traditional means (e.g. using <code>UserDefaults</code>). Plus, the <code>@Observable</code> era is the perfect time to separate <strong>Data</strong> from <strong>Persistence</strong>.</p><p>Instead of coupling your data model tightly to <code>UserDefaults</code>, consider moving that responsibility to a dedicated <strong>Service</strong> or <strong>Manager</strong>.</p><ul><li><p><strong>The Service:</strong> Handles the saving/loading logic.</p></li><li><p><strong>The Observable Model:</strong> Simply holds the current source of truth in a standard Swift type.</p></li></ul><p>This keeps your observation logic clean (no manual wiring required!) and your persistence logic isolated where it belongs.</p><div><hr></div><h2>Conclusion: Finding Your Sea Legs</h2><p>Migrating to <code>@Observable</code> is a bit like upgrading your ship&#8217;s engine from diesel to nuclear fusion. The potential for power and efficiency is incredible, but if you wire it up using the old schematics, you&#8217;re going to have a meltdown.</p><p>The most important thing to remember is the <strong>&#8220;Spotlight Rule&#8221;</strong>: The new observation system is lazy. It only updates a view if that view is currently &#8220;shining a spotlight&#8221; on the specific property that changed. If your view stops looking&#8212;even for a second, or because of a nested object&#8212;the updates stop coming.</p><p>Once you master the <strong>lazy </strong><code>.task</code><strong> initialization</strong>, strict <strong>granular access</strong> for child objects, and the <code>@Bindable</code><strong> shadow</strong> syntax, you&#8217;ll find that the new system isn&#8217;t just &#8220;Objectively Better&#8221;&#8212;it&#8217;s actually fun to use.</p><p>Until then, keep your eye on the graph, and trust your bindings.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Emptiness in SwiftUI]]></title><description><![CDATA[How "Empty" can be designed and accounted for using EmptyView, EmptyModifier, and ContentUnavailableView]]></description><link>https://captainswiftui.substack.com/p/emptiness-in-swiftui</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/emptiness-in-swiftui</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Wed, 21 Jan 2026 12:00:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!jTY8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jTY8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jTY8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png 424w, https://substackcdn.com/image/fetch/$s_!jTY8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png 848w, https://substackcdn.com/image/fetch/$s_!jTY8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png 1272w, https://substackcdn.com/image/fetch/$s_!jTY8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jTY8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png" width="1456" height="1054" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1054,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4932687,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/179511883?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jTY8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png 424w, https://substackcdn.com/image/fetch/$s_!jTY8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png 848w, https://substackcdn.com/image/fetch/$s_!jTY8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png 1272w, https://substackcdn.com/image/fetch/$s_!jTY8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78c90745-6938-4413-b026-22f6ac6663ee_2432x1760.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Did you know that zero had to be &#8220;invented&#8221;? For many ancient civilizations, numbers were exclusively for tangible things. There was no need to count nothing. Eventually, scholars recognized that &#8220;nothing&#8221; isn&#8217;t just an absence&#8212;it&#8217;s a value. It&#8217;s a placeholder, a starting point, and a critical bridge between positive and negative.</p><p>In SwiftUI, the <strong>empty state</strong> is our zero.</p><p>There will always be scenarios where there is no data to display, no modifier to apply, or no content to render. Yet, the software must still communicate this state of &#8220;nothingness&#8221; to the user&#8212;or to the compiler.</p><p>SwiftUI provides us with three distinct tools to handle emptiness, each serving a different purpose:</p><ol><li><p><code>EmptyView</code>: For the view hierarchy (Layout).</p></li><li><p><code>EmptyModifier</code>: For the type system (Compiler).</p></li><li><p><code>ContentUnavailableView</code>: For the user (Experience).</p></li></ol><p>Let&#8217;s explore how to design for nothingness.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>EmptyView: The Layout of Nothing</h2><p><code>EmptyView</code> is one of SwiftUI&#8217;s most deceptively simple types. On the surface, it feels like a placeholder you drop in when you don&#8217;t want to render anything. But its role is deeper: <code>EmptyView</code> is SwiftUI&#8217;s canonical representation of <em>nothingness</em>.</p><h3>What EmptyView <em>Actually</em> Is</h3><p><code>EmptyView</code> is a zero-sized, non-rendering view. It draws nothing, takes up no space, has no layout implications, and participates minimally in the view tree. If SwiftUI were a standard programming language, <code>EmptyView</code> would be <code>Void</code>&#8212;a way to say, &#8220;There is a concept of a view here, but it is empty.&#8221;</p><p>Under the hood, SwiftUI uses <code>EmptyView</code> as the default return type for conditional branches that don&#8217;t produce UI and for erased view builders.</p><h3>Common Use Cases</h3><h4><strong>1. Handling Optional Content</strong></h4><pre><code><code>if let user = model.user {
    UserProfileView(user: user)
} else {
    EmptyView()
}
</code></code></pre><p>This is the simplest case: you conditionally include a view, and use <code>EmptyView()</code> when there&#8217;s nothing to show.</p><h4><strong>2. Satisfying ViewBuilders</strong></h4><p>SwiftUI&#8217;s <code>@ViewBuilder</code> cannot return <code>nil</code>. It must return a View. In complex generic contexts or manual ViewBuilder implementations, <code>EmptyView</code> is the correct return type when you need to bail out of rendering.</p><h3>How EmptyView Differs From <code>.hidden()</code></h3><p>This is where many developers trip up.</p><p>Using <code>.hidden()</code> does <strong>not</strong> remove your view&#8212;it&#8217;s closer to setting <code>visibility: hidden</code> in CSS. The view stays in the layout calculation, reserves its frame size, and affects the positioning of neighbors.</p><pre><code><code>Text("Hidden")
   .hidden() // Invisible, but still takes up space
</code></code></pre><p>Using <code>EmptyView</code> removes the view entirely from the layout pass:</p><pre><code><code>EmptyView() // No space, no layout, no impact
</code></code></pre><h3>Captain&#8217;s Tip</h3><blockquote><p><em>EmptyView is the silence between notes&#8212;essential to the rhythm, but never the melody. Use it to create space, not confusion.</em></p></blockquote><div><hr></div><blockquote><p><em>This article would like to promote <a href="https://blog.jacobstechtavern.com/">Jacob&#8217;s Tech Tavern</a>:</em></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5JMl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5JMl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png 424w, https://substackcdn.com/image/fetch/$s_!5JMl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png 848w, https://substackcdn.com/image/fetch/$s_!5JMl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png 1272w, https://substackcdn.com/image/fetch/$s_!5JMl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5JMl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png" width="548" height="181.78846153846155" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:483,&quot;width&quot;:1456,&quot;resizeWidth&quot;:548,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5JMl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png 424w, https://substackcdn.com/image/fetch/$s_!5JMl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png 848w, https://substackcdn.com/image/fetch/$s_!5JMl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png 1272w, https://substackcdn.com/image/fetch/$s_!5JMl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a1b6a2-6ec6-47b3-9a10-3ae38bbc2575_2584x858.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>Jacob&#8217;s blog was one of the few that inspired me to get back into writing articles and on Substack. His topics are always interesting, in-depth, and full of good humor. And now that he&#8217;s gone full-time indie, we get to enjoy more of his great work! Check him out and consider subscribing to Jacob&#8217;s Tech Tavern, today!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.jacobstechtavern.com/&quot;,&quot;text&quot;:&quot;Jacob's Tech Tavern&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.jacobstechtavern.com/"><span>Jacob's Tech Tavern</span></a></p></blockquote><div><hr></div><h2>EmptyModifier: The Compiler&#8217;s Nothing</h2><p>If <code>EmptyView</code> represents &#8220;no view,&#8221; then <code>EmptyModifier</code> represents <strong>&#8220;no transformation.&#8221;</strong></p><p>The official documentation notes that this modifier is useful &#8220;at compile time.&#8221; This is a crucial distinction. <code>EmptyModifier</code> isn&#8217;t usually meant for runtime logic (like toggling opacity on and off); it is the <strong>Identity</strong> element of the modifier world. It exists to satisfy the type checker when a modifier is required, but you don&#8217;t actually want to do anything.</p><h3>The Power of Type Aliases</h3><p>The most powerful use case for <code>EmptyModifier</code> is combining it with <strong>Conditional Compilation</strong>.</p><p>Imagine you want a specific debug overlay&#8212;a red border or a tap gesture&#8212;but you want that code completely stripped out of your Release builds. You don&#8217;t want to wrap every call site in <code>#if DEBUG</code>.</p><p>Instead, you can define a modifier that changes based on the build configuration:</p><pre><code><code>#if DEBUG
struct DebugBorder: ViewModifier {
    func body(content: Content) -&gt; some View {
        content.overlay(
            RoundedRectangle(cornerRadius: 4)
                .stroke(.red, lineWidth: 1)
        )
    }
}
#else
// In Release builds, this becomes the "Identity" modifier
typealias DebugBorder = EmptyModifier
#endif
</code></code></pre><p>Now, your call site remains clean and consistent:</p><pre><code><code>Text("Hello World")
    .modifier(DebugBorder())
</code></code></pre><p>In a Debug build, the compiler sees a ViewModifier that draws a border.</p><p>In a Release build, the compiler sees EmptyModifier. Because EmptyModifier&#8217;s body just returns the content exactly as is, the compiler can optimize it away entirely. There is no runtime cost, no branching logic, and no leftover code artifacts.</p><h3>Why not use it for Runtime Logic?</h3><p>You might be tempted to write code like this:</p><p>view.modifier(isEnabled ? MyEffect() : EmptyModifier())</p><p>While this compiles, it usually results in the creation of a <code>_ConditionalContent</code> wrapper. For simple runtime toggling, it is often cleaner to put the logic <em>inside</em> a custom modifier or use standard view extensions.</p><p><code>EmptyModifier</code> shines when you need to provide a default value to a generic system. If you are building a reusable component that accepts a generic <code>VM: ViewModifier</code>, you can set the default to <code>EmptyModifier</code>:</p><pre><code><code>struct MyContainer&lt;VM: ViewModifier&gt;: View {
    var modifier: VM = EmptyModifier() // Default is "do nothing"
    // ...
}
</code></code></pre><h3>Captain&#8217;s Tip</h3><blockquote><p><em>EmptyModifier is the invisible rigging of your UI&#8212;unseen in release builds, but essential when you&#8217;re tuning the ship. Use it to debug boldly and deploy cleanly.</em></p></blockquote><div><hr></div><h2>The Paradox of Empty State</h2><p>&#8220;Empty&#8221; is one of the most misleading words in UI design.</p><p>In software, an empty state is never truly empty&#8212;it&#8217;s a moment of uncertainty. It&#8217;s the space where users ask: <em>What should I do next? Did something break? Is there supposed to be something here?</em></p><p>Left untreated, emptiness feels like failure. Treated well, it becomes guidance.</p><p>While <code>EmptyView</code> solves the technical problem of rendering nothing, it fails the user experience problem. An empty screen requires intention, clarity, and often a visible invitation to act.</p><h3>ContentUnavailableView: Designing for Absence</h3><p>This is precisely why SwiftUI introduced <code>ContentUnavailableView</code>.</p><p>Rather than treating empty states as an edge case or a blank canvas, <code>ContentUnavailableView</code> formalizes them. It gives emptiness a standard structure that feels &#8220;at home&#8221; on Apple platforms.</p><p>Here, we have a really basic implementation that still manages to not leave the user hanging:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T9vN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T9vN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png 424w, https://substackcdn.com/image/fetch/$s_!T9vN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png 848w, https://substackcdn.com/image/fetch/$s_!T9vN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png 1272w, https://substackcdn.com/image/fetch/$s_!T9vN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T9vN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png" width="290" height="175" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:175,&quot;width&quot;:290,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5831,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/179511883?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T9vN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png 424w, https://substackcdn.com/image/fetch/$s_!T9vN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png 848w, https://substackcdn.com/image/fetch/$s_!T9vN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png 1272w, https://substackcdn.com/image/fetch/$s_!T9vN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aeb640d-2ec8-4420-a2dc-681f005bcdee_290x175.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><pre><code>ContentUnavailableView("Emptiness!", systemImage: "bathtub", description: Text("Wow, such empty!"))</code></pre><p>This next example provides a bit more information that answers three simple questions considering &#8220;nothingness&#8221;:</p><ol><li><p><strong>What&#8217;s missing?</strong> (The Title)</p></li><li><p><strong>Why is it missing?</strong> (The Description)</p></li><li><p><strong>What can I do next?</strong> (The Action)</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dOb7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dOb7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png 424w, https://substackcdn.com/image/fetch/$s_!dOb7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png 848w, https://substackcdn.com/image/fetch/$s_!dOb7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png 1272w, https://substackcdn.com/image/fetch/$s_!dOb7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dOb7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png" width="290" height="173" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:173,&quot;width&quot;:290,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:9561,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/179511883?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dOb7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png 424w, https://substackcdn.com/image/fetch/$s_!dOb7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png 848w, https://substackcdn.com/image/fetch/$s_!dOb7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png 1272w, https://substackcdn.com/image/fetch/$s_!dOb7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8ab4c3-a354-42cf-b90a-3d3644ef7179_290x173.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><pre><code><code>ContentUnavailableView {
    Label("No Favorites", systemImage: "star.slash")
} description: {
    Text("Mark items as favorites to see them here.")
} actions: {
    Button("Browse Items") {
        // Navigate to items
    }
}
</code></code></pre><p>Instead of a blank list or a silent screen, the UI acknowledges the state. It reassures the user that the app isn&#8217;t broken&#8212;it&#8217;s just waiting.</p><p>In many cases, <code>ContentUnavailableView</code> is the right answer where developers used to reach for <code>EmptyView</code>. If a list is empty, don&#8217;t show an <code>EmptyView</code> (which shows nothing); show a <code>ContentUnavailableView</code> (which explains <em>why</em> there is nothing).</p><h3>Captain&#8217;s Tip</h3><blockquote><p><em>An empty state isn&#8217;t a failure of your UI&#8212;it&#8217;s a moment of guidance. When there&#8217;s nothing to show, your job shifts from displaying content to setting expectations. If users feel lost in an empty screen, the problem isn&#8217;t the data&#8212;it&#8217;s the design.</em></p></blockquote><div><hr></div><h2>Conclusion</h2><p>Emptiness in SwiftUI is a spectrum.</p><p>At the lowest level, we have <code>EmptyView</code>: the structural, silent void used by the layout system to reserve no space.</p><p>At the compiler level, we have <code>EmptyModifier</code>: the identity type used to strip behaviors out of release builds or satisfy generic requirements without incurring runtime cost.</p><p>And at the human level, we have <code>ContentUnavailableView</code>: the loud, helpful interface that turns a lack of data into a call to action.</p><p>As you build your apps, remember that &#8220;nothing&#8221; is a valid state that deserves just as much care as your &#8220;happy paths.&#8221; Use <code>EmptyView</code> to hide, <code>EmptyModifier</code> to optimize, and <code>ContentUnavailableView</code> to guide.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Playing with Sheet (on iOS)]]></title><description><![CDATA[A look at how Apple has reshaped modal and sheet presentations in SwiftUI for iOS]]></description><link>https://captainswiftui.substack.com/p/playing-with-sheet-on-ios</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/playing-with-sheet-on-ios</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Thu, 30 Oct 2025 11:01:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Q4T9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Q4T9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q4T9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Q4T9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Q4T9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Q4T9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q4T9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1205428,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/176566457?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Q4T9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Q4T9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Q4T9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Q4T9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05d337b6-ba29-403e-9f2b-8670b8a627b9_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There&#8217;s been ongoing&#8212;yet significant&#8212;evolution in how sheets and modals are used. The era of full-screen takeovers and heavy modals has been fading, replaced by lightweight, flexible, and fluid overlays that feel right at home in the new Liquid Glass design system.</p><p>Apple&#8217;s been steadily modernizing the way we present content&#8212;most notably through presentation detents, component roles, and a refreshed set of presentation modifiers that give developers real control over look, feel, and motion. Even the elusive and slightly odd TabView/sheet pattern from &#8220;Find My&#8221; has been cleaned up, aligning with the system&#8217;s new aesthetic.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1_bb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1_bb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg 424w, https://substackcdn.com/image/fetch/$s_!1_bb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg 848w, https://substackcdn.com/image/fetch/$s_!1_bb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!1_bb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1_bb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg" width="384" height="373.97802197802196" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1418,&quot;width&quot;:1456,&quot;resizeWidth&quot;:384,&quot;bytes&quot;:1405132,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/176566457?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1_bb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg 424w, https://substackcdn.com/image/fetch/$s_!1_bb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg 848w, https://substackcdn.com/image/fetch/$s_!1_bb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!1_bb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a93f858-d9f8-4a70-82f2-fb9544671760_1600x1558.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In this article, I wanted to take a break from the broader, high-level topics and just have some fun playing with sheet&#8212;exploring what&#8217;s new, what&#8217;s changing, and how you can adopt Apple&#8217;s updated presentation model in SwiftUI without losing your sense of flow.</p><h2><strong>Sheet Fundamentals and Modern Presentation</strong></h2><p>For years, a &#8220;sheet&#8221; in SwiftUI meant one thing: a full-screen takeover that slid up from the bottom, blocked everything behind it, and waited for the user to tap a &#8220;Done&#8221; button before giving control back. It got the job done &#8212; but it also froze the rest of the experience.</p><p>That era has long sailed away.</p><p>Today, sheets are far more flexible. They&#8217;re not just interruptions &#8212; they can be the moment, or complement it. A sheet can act as a full-screen view, a compact accessory, a sliding control panel, or a lightweight status overlay. What used to be a rigid, single-purpose UI element has evolved into one of the most dynamic tools in the developer&#8217;s toolkit.</p><p>Apple&#8217;s presentation modifiers &#8212; like <code>.presentationDetents</code>, <code>.presentationCornerRadius</code>, and <code>.presentationBackgroundInteraction</code> &#8212; capture that evolution. These aren&#8217;t just cosmetic flourishes; they represent a philosophical shift: a sheet no longer removes users from context &#8212; it expands it.</p><p>Here&#8217;s a simple example that captures that spirit:</p><pre><code>.sheet(isPresented: $showSettings) {
    SettingsView()
        .presentationDetents([.medium, .large])
        .presentationBackgroundInteraction(.enabled)
        .presentationCornerRadius(32)
}</code></pre><p>What used to be a hard stop is now a conversation between layers. The user decides how much space they need; you decide how immersive it should feel.</p><p>That&#8217;s the foundation of modern sheet design: adaptive, responsive, and gracefully contextual.</p><h3><em><strong>Captain&#8217;s Tip</strong></em></h3><p><em>If it feels like you&#8217;re breaking flow, you probably are.</em> In the Liquid Glass era, sheets should move like water &#8212; flowing with the user&#8217;s intent, not against it.</p><h2><strong>Understanding Detents &#8212; Designing in Depth</strong></h2><p>When sheets first landed in SwiftUI, they were pretty basic &#8212; useful, but blunt. You could show a modal that covered most of the screen or one that hovered partway up, and that was about it.</p><p>With presentation detents, Apple has turned sheets into a flexible, fluid part of the user experience. They can live anywhere between a full takeover and a subtle overlay &#8212; floating, snapping, or expanding based on user intent and your app&#8217;s design.</p><p>Think of detents as waypoints for your sheet &#8212; positions that define how much space the sheet occupies, how it behaves when dragged, and how the user transitions between states.</p><h3><strong>The Built-Ins: Medium and Large</strong></h3><p>The simplest detents are built right in: <code>.medium</code> and <code>.large</code>. These match Apple&#8217;s own design language &#8212; you&#8217;ll find them everywhere from Maps to Stocks.</p><p>A <code>.medium </code>detent is great for contextual views &#8212; showing filters, lists, or a now-playing interface. A <code>.large</code> detent, meanwhile, is perfect for tasks that need focus but don&#8217;t necessarily deserve a new screen.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tKMO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tKMO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!tKMO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!tKMO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!tKMO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tKMO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif" width="203" height="440.40677966101697" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:295,&quot;resizeWidth&quot;:203,&quot;bytes&quot;:3774185,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/176566457?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tKMO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!tKMO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!tKMO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!tKMO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F482b198e-5522-4823-9a8f-e2f466a00d34_295x640.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Using my MLB Tracker, we see medium and large detents at work.</figcaption></figure></div><h3><strong>Going Custom &#8212; Height and Fraction</strong></h3><p>Sometimes your sheet doesn&#8217;t fit neatly into Apple&#8217;s presets. That&#8217;s where custom detents come in:</p><pre><code>.presentationDetents([
    .fraction(0.25),
    .medium,
    .height(500)
])</code></pre><p>Here, you&#8217;re defining specific heights or proportional space allocations, giving your sheet a feel that matches your content.</p><p>Fractional heights like <code>.fraction(0.25)</code> are particularly useful when you want consistency across devices, while<code> .height() </code>gives you fine-grained control for precise layouts.</p><p>For custom, reusable, and labeled detents, you can also take advantage of <a href="https://developer.apple.com/documentation/swiftui/custompresentationdetent">CustomPresentationDetent</a> to define and set your own detents:</p><pre><code>private struct ScoreOnly: CustomPresentationDetent {
    static func height(in context: Context) -&gt; CGFloat? {
        max(48, context.maxDetentValue * 0.1)
    }
}

extension PresentationDetent {
    static let scoreOnly = Self.custom(ScoreOnly.self)
    static let smallHeight = Self.height(100)
    static let extraLargeFraction = Self.fraction(0.75)
}</code></pre><p>Here, we&#8217;ve added a detent for when we just want to show the score of the game:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k6Z3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k6Z3!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!k6Z3!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!k6Z3!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!k6Z3!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k6Z3!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif" width="203" height="440.40677966101697" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:295,&quot;resizeWidth&quot;:203,&quot;bytes&quot;:7082435,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/176566457?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!k6Z3!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!k6Z3!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!k6Z3!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!k6Z3!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c848649-3d73-47dd-88f9-a0690282c6a9_295x640.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>Selecting and Tracking Detents</strong></h3><p>You can even track the user&#8217;s chosen detent or programmatically adjust it with a binding:</p><pre><code>.presentationDetents([.medium, .large],
                     selection: $currentDetent)</code></pre><p>This lets you adapt your UI as interaction unfolds &#8212; imagine expanding your sheet when the user taps &#8220;Show Details&#8221;, or collapsing it after a confirmation. It also opens the door for subtle motion design: a medium sheet can transition seamlessly into a large one as more content loads or becomes available.</p><p>In Apple&#8217;s Stocks app, we see how tracking the selected detent actually determines the state of the content being shown. For instance, when it&#8217;s &#8220;closed&#8221;, the title says Business News, then changes the title to Top Stories in when set to the medium detent. And on large, the navigation bar transforms into a scrolling ticker.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jtUp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jtUp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif 424w, https://substackcdn.com/image/fetch/$s_!jtUp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif 848w, https://substackcdn.com/image/fetch/$s_!jtUp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif 1272w, https://substackcdn.com/image/fetch/$s_!jtUp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jtUp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif" width="276" height="597.7125" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:693,&quot;width&quot;:320,&quot;resizeWidth&quot;:276,&quot;bytes&quot;:3606419,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/176566457?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jtUp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif 424w, https://substackcdn.com/image/fetch/$s_!jtUp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif 848w, https://substackcdn.com/image/fetch/$s_!jtUp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif 1272w, https://substackcdn.com/image/fetch/$s_!jtUp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8896ff4a-f005-4ec3-86c5-96e7cd93ceab_320x693.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This enables detents to be more than just a determination of how much/little of the background content is being shown, but also all the subtle states in and around it, as well.</p><h3><em><strong>Captain&#8217;s Tip</strong></em></h3><p>Think of detents like depth markers on a ship&#8217;s hull. Each one tells you how far your UI dives beneath the surface &#8212; a careful balance between immersion and intrusion. Use them to give your users buoyancy, not ballast.</p><h2>Roles &amp; Interactivity &#8212; Customizing Sheet Behavior</h2><p>With detents you decide <em>where</em> a sheet lives. Now we&#8217;ll talk about <em>how</em> it behaves&#8212;how it interacts, how it dismisses, how it feels to tap, scroll, drag, or ignore the background behind it. These interactive modifiers turn sheets into living panels, not just pop-ups.</p><h3>Background Interaction &#8212; The Layer Lives On</h3><p>One of the biggest shifts in sheet behavior is what happens <em>behind</em> it. With <code>.presentationBackgroundInteraction(_:)</code>, you decide whether the user can still interact with the view underneath.</p><pre><code>.presentationBackgroundInteraction(.enabled(upThrough: .medium))</code></pre><p>Use this pattern when your sheet is part of a fluid interaction (e.g., a map panel). It lets users still tap and pan the map while the sheet sits at a lower detent. When the sheet expands, background interaction disables automatically&#8212;shifting focus naturally.</p><h3>Appearance &amp; Feel &#8212; Beyond Just Covering the Screen</h3><p>Customization features like <code>.presentationBackground(_:)</code>, <code>.presentationCornerRadius(_:)</code>, and <code>.presentationContentInteraction(_:)</code> let you refine how the sheet <em>looks and acts</em>.</p><pre><code>.sheet(isPresented: $showMenu) {
    MenuView()
        .presentationDetents([.height(250), .medium])
        .presentationBackground(.ultraThinMaterial)
        .presentationCornerRadius(24)
        .presentationContentInteraction(.scrolls)
}</code></pre><ul><li><p><code>.presentationBackground(.ultraThinMaterial)</code> gives that translucent glass feel.</p></li><li><p><code>.presentationCornerRadius(24)</code> softens the sheet for modern presentation.</p></li><li><p><code>.presentationContentInteraction(.scrolls)</code> helps where you have a <code>ScrollView</code> within your sheet, and you either want the scroll effect to have precedent or the drag-to-resize.</p></li></ul><h3>Dismissal Options &#8212; Different Ways of Letting Go</h3><p>For when it&#8217;s time for sheet to sail off screen, we have a number of options to trigger and handle dismissing:</p><ul><li><p>You can provide a more explicit control to dismiss a sheet by adding <code>Button(role: .close)</code> to it&#8217;s toolbar.</p></li><li><p>Use <code>.interactiveDismissDisabled(_:)</code> to prevent the user from swiping away if your sheet requires completion (e.g., a payment flow).</p></li><li><p>Use <code>@Environment(\.dismiss)</code> inside the sheet content to dismiss programmatically.</p></li><li><p>Provide an <code>onDismiss</code> closure in the <code>.sheet(...)</code> to handle any logic that needs to happen once the sheet goes away (e.g. apply the settings the user chose on the sheet)</p></li></ul><pre><code><code>.sheet(isPresented: $showForm, onDismiss: { cleanUpForm() }) {
    FormView()
        .interactiveDismissDisabled(isProcessing)
}</code></code></pre><p>This blend of intent, role, and behavior ensures the sheet aligns with your functional flow&#8212;whether it&#8217;s a quick glance, a control panel, or a committed task.</p><h3><em>Captain&#8217;s Tip</em></h3><p>Think of interactivity as sea state. A calm panel lets the waves (background) move; a deep dive sheet anchors the ship. Use these modifiers to control when the sea moves and when the ship settles.</p><h2>Give Sheet a Try</h2><p>Sheets used to be stop signs. Now, they&#8217;re flow points &#8212; a place where users can pause, peek, act, or dive deeper without ever leaving context. Sheet&#8217;s evolution to include detents, modifiers, and style controls turn what used to be a rigid pattern into something expressive and adaptive &#8212; a tool that matches the rhythm of your app, not break it&#8217;s vibe.</p><p>The real trick isn&#8217;t memorizing every modifier &#8212; it&#8217;s learning to feel when a sheet should expand, retract, scroll, or stay anchored. That&#8217;s what Apple&#8217;s evolving design language is all about: fluid layers that live together instead of on top of each other.</p><p>So experiment. Play. Let the sheet breathe with your design instead of boxing it in. Because in this new Liquid Glass era we&#8217;re all headed for, presentation isn&#8217;t interruption &#8212; it&#8217;s motion.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Northern Stars of Liquid Glass]]></title><description><![CDATA[An overview of the new HIG principles of Hierarchy, Harmony, and Consistency]]></description><link>https://captainswiftui.substack.com/p/the-northern-stars-of-liquid-glass</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/the-northern-stars-of-liquid-glass</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Wed, 17 Sep 2025 10:23:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7DoJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7DoJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7DoJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!7DoJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!7DoJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!7DoJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7DoJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1151528,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/173573724?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7DoJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!7DoJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!7DoJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!7DoJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df46ae8-b08a-4b5e-8c46-3c222cb24528_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With the release of [your platform here]OS 26, <strong>Liquid Glass is officially here</strong>. And with it comes a new era under Apple&#8217;s new design system. It&#8217;s been a fun summer exploring LG alongside the community &#8212; especially as each beta changed this, that, and everything in between. But now, with the official release, we can expect things to (mostly) settle into place for a while.</p><p>This also means the era of &#8220;we&#8217;ll wait because they keep changing things&#8221; is officially over. Sure, we get a <a href="https://www.donnywals.com/opting-your-app-out-of-the-liquid-glass-redesign-with-xcode-26/">pass for Xcode 26</a>, but starting with Xcode 27+ Liquid Glass becomes the default system in every build.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>That makes now the perfect time to understand the <strong>three principles at the heart of Liquid Glass</strong>. According to Apple&#8217;s updated <a href="https://developer.apple.com/design/human-interface-guidelines">Human Interface Guidelines</a>, they are <strong>Hierarchy, Harmony, and Consistency</strong>:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ueFc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ueFc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png 424w, https://substackcdn.com/image/fetch/$s_!ueFc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png 848w, https://substackcdn.com/image/fetch/$s_!ueFc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png 1272w, https://substackcdn.com/image/fetch/$s_!ueFc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ueFc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png" width="1456" height="736" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:736,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:381971,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/173573724?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ueFc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png 424w, https://substackcdn.com/image/fetch/$s_!ueFc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png 848w, https://substackcdn.com/image/fetch/$s_!ueFc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png 1272w, https://substackcdn.com/image/fetch/$s_!ueFc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73f7192-34d4-4269-94b4-815acc5208c7_1542x780.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Screenshot of the three HIG principles (<a href="https://developer.apple.com/design/human-interface-guidelines">Apple HIG</a>)</figcaption></figure></div><p>While Apple introduces these principles in the HIG and touched on them during the <a href="https://developer.apple.com/videos/play/wwdc2025/102/?time=176">Platforms State of the Union</a>, there&#8217;s no single, in-depth guide from Apple that shows how to apply them in practice. So let&#8217;s fill that gap &#8212; breaking down what each principle means for modern UX and how it translates into real-world SwiftUI.</p><div><hr></div><h3><strong>Hierarchy &#8212; The Lighthouse of User Attention</strong></h3><p>When Apple talks about <strong>Hierarchy</strong> in Liquid Glass, it&#8217;s not about vertical order (top vs. bottom of a screen). It&#8217;s about <strong>layering</strong> &#8212; which elements float above your content to guide interaction and which stay embedded in content.</p><p>Liquid Glass is optimized for UI elements that <strong>sit above</strong> the main canvas: navigation bars, tab bars, toolbars, sidebars, and menus. Apple&#8217;s new design language turns these controls into <strong>translucent, weightless surfaces</strong> that make the content beneath feel present and alive &#8212; instead of suffocating it.</p><p>The result:</p><ul><li><p><strong>Foreground layers</strong> = guidance and <em>controls</em></p></li><li><p><strong>Background layers</strong> = immersive <em>content</em></p></li><li><p>Clear, immediate hierarchy for the user&#8217;s eyes and fingers</p></li></ul><p>Some examples of how Liquid Glass already aids the hierarchy principle can be found in toolbars and tabview:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-pCV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-pCV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png 424w, https://substackcdn.com/image/fetch/$s_!-pCV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png 848w, https://substackcdn.com/image/fetch/$s_!-pCV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png 1272w, https://substackcdn.com/image/fetch/$s_!-pCV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-pCV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png" width="794" height="380" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:380,&quot;width&quot;:794,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24110,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/173573724?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-pCV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png 424w, https://substackcdn.com/image/fetch/$s_!-pCV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png 848w, https://substackcdn.com/image/fetch/$s_!-pCV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png 1272w, https://substackcdn.com/image/fetch/$s_!-pCV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe4f8f42-f460-4762-925d-9e50ccf25e26_794x380.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Screenshot from <a href="https://developer.apple.com/documentation/TechnologyOverviews/adopting-liquid-glass">Adopting Liquid Glass</a></figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mJMG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mJMG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png 424w, https://substackcdn.com/image/fetch/$s_!mJMG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png 848w, https://substackcdn.com/image/fetch/$s_!mJMG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png 1272w, https://substackcdn.com/image/fetch/$s_!mJMG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mJMG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png" width="794" height="209" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:209,&quot;width&quot;:794,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:95491,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/173573724?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mJMG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png 424w, https://substackcdn.com/image/fetch/$s_!mJMG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png 848w, https://substackcdn.com/image/fetch/$s_!mJMG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png 1272w, https://substackcdn.com/image/fetch/$s_!mJMG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70e40bb7-039b-48a1-b551-9e96a9a184dd_794x209.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Screenshot from <a href="https://developer.apple.com/documentation/TechnologyOverviews/adopting-liquid-glass">Adopting Liquid Glass</a></figcaption></figure></div><p>We see how core points of interaction, navigation, and functionality do not hinder the main content, but are also elevated into prominence.</p><p><strong>How to apply it in SwiftUI:</strong><br>In many cases (like with toolbars and tabviews), the LG system already sets us up for great hierarchy. But, if we were creating a more custom experience, we should consider the layers of the experience we&#8217;re presenting to our users:</p><pre><code><code>VStack(alignment: .leading, spacing: 8) {
    Text("Button")
        .font(.largeTitle)
        
    Text("...")
        .font(.body)
    
    HStack {
        Spacer()

        Button {
            // something
        } label: {
            Text("Accept")
        }
            .buttonStyle(.glass)

        Spacer()
    }
}
.padding()
.background(.green.opacity(0.3))</code></code></pre><p>The result when repeating in different button styles shows:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6qVq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6qVq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png 424w, https://substackcdn.com/image/fetch/$s_!6qVq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png 848w, https://substackcdn.com/image/fetch/$s_!6qVq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png 1272w, https://substackcdn.com/image/fetch/$s_!6qVq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6qVq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png" width="393" height="690" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:690,&quot;width&quot;:393,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75578,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/173573724?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6qVq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png 424w, https://substackcdn.com/image/fetch/$s_!6qVq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png 848w, https://substackcdn.com/image/fetch/$s_!6qVq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png 1272w, https://substackcdn.com/image/fetch/$s_!6qVq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbc2c764-bd63-4907-ad6d-db15d795fb83_393x690.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Without glass, the button blends into the (very basic) UI, remaining relatively flat even with the bordered style. But <em>with</em> glass, the button stands out from the content beneath, making it clear that this is a point of interaction and, potentially, state change.</p><p>Glass effects already promote hierarchy and naturally produce layering&#8212;even on the same literal Z-layer. Think of it as raising user attention to the surface where you need it, instead of piling on more stacks. In Liquid Glass, you don&#8217;t fight for hierarchy &#8212; you reveal it.</p><blockquote><p><strong>Captain&#8217;s Tip:</strong> When it comes to hierarchy, think &#8220;layers&#8221;. The top-most layers (nav bars, toolbars, tab bars) should guide interaction and feel <strong>lighter</strong>. The bottom layers (content views) should be <strong>primary</strong> and immersive.</p></blockquote><div><hr></div><h3><strong>Harmony &#8212; Keeping the Currents Smooth</strong></h3><p>If Hierarchy is about which elements rise to the surface, Harmony ensures those elements move together as one current. It&#8217;s not just visual polish &#8212; Harmony is spacing, rhythm, and consistency that prevent your layered UI from feeling like a sticker book of floating widgets.</p><p>Think of Harmony as <em>composition</em>:</p><ul><li><p>The translucency of glass means elements share visual &#8220;DNA&#8221; with the content beneath.</p></li><li><p>Spacing and padding must be tuned so floating elements don&#8217;t feel like they&#8217;re crashing into each other.</p></li><li><p>Motion, blur, and tint should echo across layers so the UI feels orchestrated, not random.</p></li></ul><p>One of the best and coolest examples of harmony is in the new <a href="https://developer.apple.com/documentation/SwiftUI/View/backgroundExtensionEffect()">backgroundExtensionEffect</a>. We&#8217;ve already seen how toolbars and tabviews hover over content. But the extension modifier lets you add context where the system can&#8217;t, maintaining visual continuity and harmony.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LjYp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LjYp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png 424w, https://substackcdn.com/image/fetch/$s_!LjYp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png 848w, https://substackcdn.com/image/fetch/$s_!LjYp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png 1272w, https://substackcdn.com/image/fetch/$s_!LjYp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LjYp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png" width="866" height="439" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:439,&quot;width&quot;:866,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:195448,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/173573724?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LjYp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png 424w, https://substackcdn.com/image/fetch/$s_!LjYp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png 848w, https://substackcdn.com/image/fetch/$s_!LjYp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png 1272w, https://substackcdn.com/image/fetch/$s_!LjYp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fa945b8-b0ce-4a82-842f-1ff507fc9651_866x439.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Screenshot from <a href="https://developer.apple.com/documentation/TechnologyOverviews/adopting-liquid-glass">Adopting Liquid Glass</a></figcaption></figure></div><p>Harmony also depends on grouping related elements together within clear, recognizable boundaries. In Liquid Glass, this is reinforced through <strong>Concentricity</strong>&#8212;rounded, nested shapes that echo each other&#8212;eliminating harsh edges that could feel jarring against content. You can see this in the sidebar from the extension screenshot above. You&#8217;ll also find it in the highlighted screenshot of the Maps app below. Notice the way areas of focus are grouped in concentric &#8220;containers&#8221;, reducing visual noise while reinforcing relationships between actions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kYGz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kYGz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png 424w, https://substackcdn.com/image/fetch/$s_!kYGz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png 848w, https://substackcdn.com/image/fetch/$s_!kYGz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png 1272w, https://substackcdn.com/image/fetch/$s_!kYGz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kYGz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png" width="264" height="505" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:505,&quot;width&quot;:264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:163879,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/173573724?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kYGz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png 424w, https://substackcdn.com/image/fetch/$s_!kYGz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png 848w, https://substackcdn.com/image/fetch/$s_!kYGz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png 1272w, https://substackcdn.com/image/fetch/$s_!kYGz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd446a77-fcd8-4a2d-967f-e4e6033a2a58_264x505.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Screenshot from <a href="https://developer.apple.com/videos/play/wwdc2025/102/?time=430">PSOTU</a></figcaption></figure></div><p>Note: Apple has made it a point that concentric design is so helpful in distinguishing features harmoniously that it&#8217;s used throughout Apple hardware design, as well.</p><p><strong>How to apply it in SwiftUI:</strong><br>Much of what keeps harmony is provided for us through many of the components already found in SwiftUI under the new design system. In the following screenshot, concentricity, grouping, spacing, and overlapping (without inteference) is all handled simply by adding components like TabView, tabViewBottomAccessory, and ToolbarItem. Even the rows were given concentricity when applying row spacing:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5Dsy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5Dsy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png 424w, https://substackcdn.com/image/fetch/$s_!5Dsy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png 848w, https://substackcdn.com/image/fetch/$s_!5Dsy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png 1272w, https://substackcdn.com/image/fetch/$s_!5Dsy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5Dsy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png" width="215" height="467.4378109452736" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2622,&quot;width&quot;:1206,&quot;resizeWidth&quot;:215,&quot;bytes&quot;:480568,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/173573724?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5Dsy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png 424w, https://substackcdn.com/image/fetch/$s_!5Dsy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png 848w, https://substackcdn.com/image/fetch/$s_!5Dsy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png 1272w, https://substackcdn.com/image/fetch/$s_!5Dsy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3189aff-848c-4873-8ae4-83d860fb8e82_1206x2622.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When you need to introduce harmony where there is more custom/unique UI, there&#8217;s help in tools like <a href="https://developer.apple.com/documentation/swiftui/concentricrectangle">ConcentricRectangle</a> and backgroundExtensionEffect.</p><blockquote><p><strong>Captain&#8217;s Tip:</strong> Harmony is your current &#8212; it is the tide that quietly carries your users attention from one destination on screen to the next. If one element splashes too loudly, the whole current feels off.</p></blockquote><div><hr></div><h3><strong>Consistency &#8212; Building Trust Across the Voyage</strong></h3><p>If Hierarchy is about <em>what rises above</em> and Harmony is about <em>how everything moves together</em>, Consistency is about <em>predictability</em>. It&#8217;s making sure your UI behaves, looks, and feels familiar &#8212; not just across screens, but across Apple&#8217;s entire platform fleet.</p><p>Consistency isn&#8217;t about sameness or stifling creativity. It&#8217;s about creating a dependable mental model so users can instantly understand and navigate your experience. In the Liquid Glass era, that extends across:</p><ul><li><p><strong>Apps on the same platform:</strong> Shared navigation gestures, familiar placements of toolbars/tabviews, coherent typography.</p></li><li><p><strong>Across Apple platforms:</strong> iOS, iPadOS, macOS, visionOS, watchOS, and tvOS &#8212; each with its own scale but unified materials, controls, and motion principles.</p></li><li><p><strong>Across states of your own app:</strong> Light/Dark Mode, compact/expanded, windowed/fullscreen, folded/unfolded devices.</p></li></ul><p><strong>How to apply it in SwiftUI:</strong><br>By using system components, environment-driven layout, and shared modifiers (rather than reinventing the wheel per screen), maintaining consistency could be as simple as:</p><pre><code><code>var body: some View {
    ViewThatFits {
        NavigationSplitView {
            List(games) { game in
                GameRow(game)
            }
            .listRowSpacing(8)
            .navigationTitle("MLB Scores")
        } detail: {
            GameDetailSheetView()
        }
        
        NavigationStack {
            List(games) { game in
                GameRow(game)
            }
            .listRowSpacing(8)
            .navigationTitle("MLB Scores")
        }
    }
}</code></code></pre><p>Here, we simply rely on ViewThatFits to determine whether we use a SplitView (with a defined detail view) for iPadOS/macOS or a Stack for iOS. Everything else stays the same. This may be a tad over-simplistic, but it highlights how consistency can be achieved with very little. Just look at how the experience changes at various sizes:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HVZ4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HVZ4!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 424w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 848w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 1272w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif" width="416" height="289.9" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:223,&quot;width&quot;:320,&quot;resizeWidth&quot;:416,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HVZ4!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 424w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 848w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 1272w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Captain&#8217;s Tip:</strong> Consistency is your compass, letting users sail confidently between your screens and across Apple&#8217;s platforms. It isn&#8217;t just a guideline &#8212; and it doesn&#8217;t mean cloning your UI everywhere. It&#8217;s about letting users feel at home no matter where they sail. Consistency is the glue holding the entire experience together as windows float, fold, or fade.</p><div><hr></div><h3><strong>Navigating by the Northern Stars</strong></h3><p>We&#8217;ve charted three distinct &#8220;stars&#8221; of Liquid Glass &#8212; <strong>Hierarchy</strong>, <strong>Harmony</strong>, and <strong>Consistency</strong> &#8212; but in practice, they&#8217;re never separate. They&#8217;re constellations, working together to guide your users through a seamless experience.</p><p>Hierarchy gives users a clear beacon of interaction. Harmony ensures those interactions flow naturally and feel connected. Consistency builds the trust that lets them navigate confidently across your app and Apple&#8217;s platforms.</p><p>When you apply all three, you&#8217;re not just following Apple&#8217;s design principles &#8212; you&#8217;re creating experiences that feel effortless, resilient, and future-ready.</p><p>As Liquid Glass becomes the standard, these principles aren&#8217;t checkboxes. They&#8217;re habits &#8212; ways of thinking about layers, balance, and predictability from the start of your design process. By adopting them now, you&#8217;ll spend less time &#8220;retro-fitting&#8221; later and more time innovating.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Great Shift in Apple Development]]></title><description><![CDATA[A new, sweeping era has begun. Here are the signs...]]></description><link>https://captainswiftui.substack.com/p/the-great-shift-in-apple-development</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/the-great-shift-in-apple-development</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Tue, 02 Sep 2025 18:14:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!VpjL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VpjL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VpjL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!VpjL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!VpjL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!VpjL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VpjL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1679649,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/170305918?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VpjL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!VpjL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!VpjL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!VpjL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f257ec-fe0f-437d-bfed-6e6708014229_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This summer has really felt like a busy one as an Apple Developer. I feel I've spent much of it jumping from topic to topic, trying to piece together just how projects may (or may not) be impacted (either now or in the future).</p><p>Of course, diving deep into Liquid Glass was an obvious whale of a topic to wade through. There was also iPadOS Windowing and the foldable iPhone production news that began to introduce new sizing and perspective considerations, adding UX design complexity. And, as I continued to convert some of my projects over to Swift 6, working through concurrency issues became a past time.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Absorbing these and a slew of other topics felt more taxing than normal. You can tell based off my writing (or lack, thereof). There were pre-WWDC indications that there would be large changes coming (and I did attempt to brace myself and others for them). As developers, we sign on to a career of constantly learning and adapting as technology evolves and emerges.</p><p>But I decided to take a step back, breathe in the salty air, and reflect on all these changes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GHEb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GHEb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GHEb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GHEb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GHEb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GHEb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg" width="412" height="549.239010989011" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1941,&quot;width&quot;:1456,&quot;resizeWidth&quot;:412,&quot;bytes&quot;:3718452,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/170305918?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GHEb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GHEb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GHEb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GHEb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F382fd8f5-3831-4796-87ea-42d56a14d803_3024x4032.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">I was actually asked if I was a Captain minutes after this photo was taken. I said yes (with explanations, of course)</figcaption></figure></div><p>During my reflections, it finally hit me: we&#8217;ve now entered a new era of Apple Development, and we&#8217;re currently smack dab in the middle of The Great Shift (at least, that&#8217;s what I&#8217;m calling it).</p><p>Let me explain&#8230;</p><h2>Swift 6 Is A New Way of Coding</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pVAY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pVAY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png 424w, https://substackcdn.com/image/fetch/$s_!pVAY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png 848w, https://substackcdn.com/image/fetch/$s_!pVAY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png 1272w, https://substackcdn.com/image/fetch/$s_!pVAY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pVAY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png" width="320" height="100" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:100,&quot;width&quot;:320,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pVAY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png 424w, https://substackcdn.com/image/fetch/$s_!pVAY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png 848w, https://substackcdn.com/image/fetch/$s_!pVAY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png 1272w, https://substackcdn.com/image/fetch/$s_!pVAY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cdbed79-2946-4daf-ab7f-23db1cfd45da_320x100.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>When Swift 6 was declared to be a large, concurrency-pushing, thread-safety enforcing update, developers rejoiced! As we were slowly introduced in later Swift 5 versions to some of the core features (such as Actors, async/await, and Tasks) there was growing excitement for what was to come!</p><p>I do think, however, that the vast majority of developers underestimated what concepts like &#8220;strict-concurrency&#8221; would actually entail. For anyone who has undergone a migration to Swift 6, you may have said to yourself at one point &#8220;was my code really that unsafe?&#8221;. And the answer is yes, it really was.</p><p>For years, even slightly experienced Swift developers had some awareness of threading and concurrency (probably through Grand Central Dispatch). I&#8217;ve seen many Juniors first encounter <code>Dispatch.main</code> when their UI was failing to react to data changes that were happening on another thread, unbeknownst to them.</p><p>This new era of Swift will change all of that. Knowing concurrency concepts and the tools/frameworks supporting them will no longer be just a distinguishing factor between career levels and sets of interview questions: it is now universally required understanding.</p><p>Thank goodness for that. Once you get over the initial panic and fear of a gazillion concurrency warnings and errors, you begin to understand the actual healing taking place in your code. That rich reward, itself, allows you to slowly embrace how you need to code in Swift from now on.</p><h2>Liquid Glass Enables Fluid Designs</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!knF6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!knF6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!knF6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!knF6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!knF6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!knF6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg" width="538" height="302.625" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:538,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;WWDC25: Meet Liquid Glass | Apple&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="WWDC25: Meet Liquid Glass | Apple" title="WWDC25: Meet Liquid Glass | Apple" srcset="https://substackcdn.com/image/fetch/$s_!knF6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!knF6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!knF6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!knF6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0056ecc8-eba4-4aa0-a121-5b29eb57d6ee_1280x720.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Liquid Glass embodies a host of liquid puns. <em>Clearly,</em> the &#8220;material&#8221; part of the design is quite <em>transparent</em>. The minimizing of components (such as TabView and Toolbars) creates less of a <em>splash</em> atop app content. The transitions, interactions, and presentations provide a <em>fluid</em> experience that allows users to feel they&#8217;re <em>floating</em> from feature to feature.</p><p>However, Liquid Glass is not just material facelift. As Apple has stated, Liquid Glass is a &#8220;new design system&#8221;. This means there is a new vision and direction for how Apple wants us to design applications on its platforms. The <a href="https://developer.apple.com/design/human-interface-guidelines">HIG</a> reflects this as it prominently displays the new core design principles: Hierarchy, Harmony, and Consistency.</p><p>As I <em>dove</em> into Liquid Glass this summer, I began to better understand how these principles guide apps into the next era of software and mobile. That the glimpses at some of the new features (and rumored features) to lead us to a vast <em>sea</em> of possibilities ahead. At the same time, failing to adopt Liquid Glass could leave your app feeling dated, behind-the-curve, or worse: broken.</p><h2>Windowing and Foldables Shatter Size Class Conventions</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KeFO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KeFO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg 424w, https://substackcdn.com/image/fetch/$s_!KeFO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg 848w, https://substackcdn.com/image/fetch/$s_!KeFO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!KeFO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KeFO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg" width="490" height="350" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:980,&quot;resizeWidth&quot;:490,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;iPadOS 26 introduces powerful new features that push iPad even further -  Apple&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="iPadOS 26 introduces powerful new features that push iPad even further -  Apple" title="iPadOS 26 introduces powerful new features that push iPad even further -  Apple" srcset="https://substackcdn.com/image/fetch/$s_!KeFO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg 424w, https://substackcdn.com/image/fetch/$s_!KeFO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg 848w, https://substackcdn.com/image/fetch/$s_!KeFO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!KeFO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaeac279-813a-4c94-ae5e-baff3ad13662_980x700.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you&#8217;re a web/desktop-app developer, you&#8217;re laughing at all the mobile developers befuddled at Windowing on iPadOS. Accounting for dynamic sizing and displaying of applications is par-the-course. But for Mobile, that static rigidity of size classes has been a solid staple of design and requirements.</p><p>Even with Split View on iPad, there has always been some way of planning ahead for how your app looked in a seemingly fixed set of scenarios. Through the years, I&#8217;ve even seen designs get updates when a new iPhone&#8217;s dimensions were announced. iPhone X was a shocker with the screen going (seemingly) edge to edge (sans notch).</p><p>Now, however, we have to concern ourselves with more dynamic scenarios, including a minimum size that beats out the iPhone SE.</p><p>To make things even more complicated, we know that a foldable iPhone is just about a year away. We can start to guess how it will look, but until we actually see it we have no idea what new dimensions iPhone apps will now have to take into account.</p><p>Harkening back to Liquid Glass, this idea of having a more <em>fluid</em> and <em>dynamic</em> design for apps seems to fit right in. Maybe the flattening of component design and focus on core functionality are key to these &#8220;next steps&#8221;, after all. As the principle of Consistency states: &#8220;Adopt platform conventions to maintain a consistent design that <em>continuously adapts across window sizes and displays</em>.&#8221; If we don&#8217;t adhere to this principle, our apps may literally not fit the devices of tomorrow.</p><h2>Snippets, Widgets, Intents: Oh My!</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yGpP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yGpP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg 424w, https://substackcdn.com/image/fetch/$s_!yGpP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg 848w, https://substackcdn.com/image/fetch/$s_!yGpP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!yGpP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yGpP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg" width="502" height="282.375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:502,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Design interactive snippets - WWDC25 - Videos - Apple Developer&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Design interactive snippets - WWDC25 - Videos - Apple Developer" title="Design interactive snippets - WWDC25 - Videos - Apple Developer" srcset="https://substackcdn.com/image/fetch/$s_!yGpP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg 424w, https://substackcdn.com/image/fetch/$s_!yGpP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg 848w, https://substackcdn.com/image/fetch/$s_!yGpP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!yGpP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa458a55e-f7b9-4e3b-9838-ee3ba285c304_1800x1012.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Apple is pushing for an ecosystem where the features of your app are not confined by your apps instance: they want your features to be open, accessible, and available to the platform, at-large.</p><p>Widgets are not new, but they have consistently seen some kind of update at every WWDC since they arrived. Their inclusion in CarPlay is a huge barrier-busting announcement.</p><p>The push for snippets was also interesting to see this year. They are not widgets, but are of the class of mini-features, complete with UI. Think of when you ask Siri what the weather is and it shows a thin rectangle from the Weather app.</p><p>Lastly, App Intents have always been promoted as ways to expose your app features, particularly through non-UI methods. They influence Siri prompts, could work with Shortcuts, and are promised to have a significant role in Apple Intelligence.</p><p>Which is why I view these three &#8220;channels&#8221; as part of The Great Shift. I believe they are a part of an app-less, more-platform future for software. A world where users may end up using your features and content more from the platform than from your actual app.</p><h3>An App-less What-If&#8230;</h3><p>Picture this: a user wants to know the wait time for a ride at an amusement park. They could open the park&#8217;s app, navigate to the rides section, scroll to the ride, tap to look at it&#8217;s details, and see the wait time. Or, the user asks the (eventual) Apple Intelligent Siri for the wait time, and Siri pulls up a snippet that displays the ride name, wait time, and other minor details (requirements, &#8220;fun-level&#8221;, etc), all in the UI style of the park and ride.</p><h2>This Thing Called AI</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nNRk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nNRk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg 424w, https://substackcdn.com/image/fetch/$s_!nNRk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg 848w, https://substackcdn.com/image/fetch/$s_!nNRk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!nNRk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nNRk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg" width="500" height="282" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:282,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Meet the Foundation Models framework - WWDC25 - Videos - Apple Developer&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Meet the Foundation Models framework - WWDC25 - Videos - Apple Developer" title="Meet the Foundation Models framework - WWDC25 - Videos - Apple Developer" srcset="https://substackcdn.com/image/fetch/$s_!nNRk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg 424w, https://substackcdn.com/image/fetch/$s_!nNRk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg 848w, https://substackcdn.com/image/fetch/$s_!nNRk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!nNRk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f94351b-f80a-47f6-8cd1-1c136b60f599_500x282.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Without a doubt, AI has become a seismic force in software development (for good, bad, and everything in between). While a great deal of the AI revolution is happening beyond Apple, they&#8217;ve clearly begun to bring it into the Apple ecosystem. Whether Apple is doing enough is a debate I&#8217;ll happily leave to pundits and hot-take artists.</p><p>But consider these points:</p><ul><li><p>We already need to consider how Apple Intelligence interacts with our app (or, perhaps, doesn&#8217;t)</p></li><li><p>With Foundation Models, we can begin to consider introducing basic AI capabilities into our app at no cost (just limitations)</p></li><li><p>Xcode 26 comes with a built-in AI assistant geared towards Apple Development</p></li></ul><p>With AI influencing so much of Apple&#8217;s platforms and frameworks, it&#8217;s absolutely a large part of The Great Shift. We must adopt thinking through how AI can impact a project as it could make a world of difference to your users (and, potentially, your competition).</p><h2>A Worthy Measure of The Great Shift</h2><p>Besides all the evidence above, there&#8217;s another way I&#8217;ve taken notice of The Great Shift.</p><p>Let&#8217;s say you were to new to iOS development and wanted to start a File &#8594; New Project with Swift 6 and Liquid Glass enabled. The majority of books, resources, and tutorials will fail to properly prepare you for those two (completely game-changing) concepts, alone.</p><p>Heck (my publisher is gonna kill me for this) the book I co-authored just a year ago (<a href="https://www.amazon.com/Swift-Cookbook-recipes-developing-applications/dp/1803239581/ref=sr_1_1_sspa?crid=1WJVB3P53N9ZE&amp;keywords=swift+cookbook+third+edition+bolella&amp;qid=1756731769&amp;sprefix=swift+cookbook+third+edition+bolella%2Caps%2C69&amp;sr=8-1-spons&amp;sp_csd=d2lkZ2V0TmFtZT1zcF9tdGY&amp;psc=1">Swift Cookbook: Third Edition</a>) is already outdated! Yes, a lot of resources begin to become outdated almost the moment they hit shelves. But usually section by section, chapter by chapter, and over time.</p><p>This past year, Apple changed the game in tons of spaces. How we code, how we build UI, and even how our app will exist on the platforms they run on. When a vast collection of resources all of a sudden become (or are about to become) outdated, that feels like solid confirmation of a large shift.</p><p>There are other ways of confirming The Great Shift. There&#8217;s the impact to your team&#8217;s backlog, your app becoming unusable in Liquid Glass, the inability to use a new Swift 6.2 feature in your code because you haven&#8217;t migrated out of sheer panic.</p><p>But, I digress. The fact of the matter is, there&#8217;s enough evidence to say that, if you were an Apple developer even just 2 years ago, you have felt The Great Shift happen in some capacity.</p><h2>Rolling With The Tide</h2><p>How do we account for The Great Shift? We do what developers have done at every great wave of change that comes their way: brace themselves as they sail right into it, with strong determination and a hunger for exploration and adventure in their belly.</p><p>We are entering uncharted waters, for sure, as we don&#8217;t even have the final versions of Xcode and OS&#8217;s. But know that you won&#8217;t be alone. As a writer in this community, I&#8217;ve learned more and more about how awesome the Apple developer community really is. And not just my fellow writers, but the developers who share comments, findings, and suggestions. Who ping me or others with support, encouragement, and gists.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BKHQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BKHQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!BKHQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!BKHQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!BKHQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BKHQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png" width="390" height="260.0892857142857" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:390,&quot;bytes&quot;:3222679,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/170305918?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BKHQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!BKHQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!BKHQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!BKHQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e7349ec-91c4-4d87-9c64-773d75007ba6_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As the Captain, I&#8217;m proud to be a part of this with you all. So let&#8217;s raise anchor, roll down the sails, and set course for what&#8217;s next as we venture into The Great Shift, together.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Windowing on iPadOS (Or How I Learned to Love The Backlog Bomb)]]></title><description><![CDATA[The New Windowing System brings iPadOS even closer to macOS, but opens up a world of new development considerations]]></description><link>https://captainswiftui.substack.com/p/windowing-on-ipados-or-how-i-learned</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/windowing-on-ipados-or-how-i-learned</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Tue, 15 Jul 2025 11:02:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!WxCG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WxCG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WxCG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!WxCG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!WxCG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!WxCG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WxCG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1604176,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WxCG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!WxCG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!WxCG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!WxCG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b207669-65ff-4304-afa0-bdcfcadf40f3_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Another WWDC, another step closer to macOS and iPadOS merging. This year, it&#8217;s official: <strong>windowing</strong> has arrived on iPad &#8212; with resizable windows, top-left traffic lights, and full menu bar support.</p><p>For iPad users, this is certainly a welcomed change and brings about hope that, one day, the two platforms will truly become one (Where&#8217;s Xcode on iPad already?).</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>On the developer front, if you thought Liquid Glass was the biggest hit to your teams backlog this year, wait until you run your app through the Windowing system. If your app has multitasking enabled, your app is open to a number of potential new states to account for.</p><ul><li><p>For pure iPad experiences, you may need to account for iPhone-sized scenarios (even if you&#8217;ve accounted for side-by-side)</p></li><li><p>For cross-platform apps, you could bring your iPhone experience to iPad</p></li><li><p>States could exist that are between iPad and iPhone (iPhone feel with iPad components) and could be previews of phone form factors to come</p></li><li><p>A new micro-state now exists</p></li></ul><h2>Turning MLB Tracker into an iPad App (Kinda)</h2><p>To quickly convert <a href="https://github.com/dbolella/MLBTracker">MLB Tracker</a> (my WWDC Demo app) to have an iPad Variant, I took advantage of <code>ViewThatFits</code>. This allowed me to do a few things:</p><ul><li><p>Be able to switch between <code>NavigationSplitView</code> and <code>NavigationStack</code></p></li><li><p>Watch how and when iPadOS would decide to switch between split and stack</p></li><li><p>See if there were any in-between states</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/dbolella/MLBTracker&quot;,&quot;text&quot;:&quot;MLB Tracker on Github&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/dbolella/MLBTracker"><span>MLB Tracker on Github</span></a></p><p>For both the Scores and Standings experiences, I used something like the following:</p><pre><code><code>ViewThatFits {
    NavigationSplitView {
        SummaryTemplateView(
            ...
        )
    } detail: {
        GameDetailSheetView()
    }
    
    NavigationStack {
        SummaryTemplateView(
            ...
        )
    }
}</code></code></pre><p>Simple, but enough to experiment with.</p><h2>A Chronicle of Changes at Different Window Sizes</h2><p>Overall, this is how MLB Tracker looks at various windowing states:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HVZ4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HVZ4!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 424w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 848w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 1272w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif" width="500" height="348.4375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:223,&quot;width&quot;:320,&quot;resizeWidth&quot;:500,&quot;bytes&quot;:8891837,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HVZ4!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 424w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 848w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 1272w, https://substackcdn.com/image/fetch/$s_!HVZ4!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27386bab-544a-4861-b14c-fffd6bc131ce_320x223.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Sorry for the crummy resolution. Had to meet file size limitations.</figcaption></figure></div><p>You&#8217;ll notice that there&#8217;s actually a few states as we scale the window size down. Unfortunately, scaling the size back up doesn&#8217;t automatically restore the larger state, either.</p><p>Here&#8217;s a breakdown of the various states.</p><h3>Portrait Full</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7T0E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7T0E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png 424w, https://substackcdn.com/image/fetch/$s_!7T0E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png 848w, https://substackcdn.com/image/fetch/$s_!7T0E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png 1272w, https://substackcdn.com/image/fetch/$s_!7T0E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7T0E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png" width="438" height="630.2266483516484" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2095,&quot;width&quot;:1456,&quot;resizeWidth&quot;:438,&quot;bytes&quot;:347271,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7T0E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png 424w, https://substackcdn.com/image/fetch/$s_!7T0E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png 848w, https://substackcdn.com/image/fetch/$s_!7T0E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png 1272w, https://substackcdn.com/image/fetch/$s_!7T0E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3ccf942-47f8-483a-9d0b-34c755cd7f98_1640x2360.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Landscape Full: iPad TabView / Split</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uv29!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uv29!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!Uv29!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!Uv29!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!Uv29!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uv29!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png" width="630" height="437.88461538461536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1012,&quot;width&quot;:1456,&quot;resizeWidth&quot;:630,&quot;bytes&quot;:291919,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Uv29!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!Uv29!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!Uv29!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!Uv29!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b06c4e-ef76-4b07-96d7-5f17b7e15ea4_2360x1640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Resized: iPad TabView / Switched to Stack</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IBgG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IBgG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!IBgG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!IBgG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!IBgG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IBgG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png" width="631" height="438.5796703296703" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1012,&quot;width&quot;:1456,&quot;resizeWidth&quot;:631,&quot;bytes&quot;:2676901,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IBgG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!IBgG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!IBgG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!IBgG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f5a6e08-544b-4c1c-8614-3e962f96da5e_2360x1640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Resized More: iPhone TabView / Still Stack</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HGYU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HGYU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!HGYU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!HGYU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!HGYU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HGYU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png" width="630" height="437.88461538461536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1012,&quot;width&quot;:1456,&quot;resizeWidth&quot;:630,&quot;bytes&quot;:4021822,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HGYU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!HGYU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!HGYU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!HGYU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce51627c-6f23-4c39-bae9-eba695c12207_2360x1640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Minimum Size: Smaller than iPhone SE</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i9pV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i9pV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!i9pV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!i9pV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!i9pV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i9pV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png" width="630" height="437.88461538461536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f4556325-e377-4098-b113-83411f7f3d62_2360x1640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1012,&quot;width&quot;:1456,&quot;resizeWidth&quot;:630,&quot;bytes&quot;:4380248,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!i9pV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!i9pV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!i9pV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!i9pV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4556325-e377-4098-b113-83411f7f3d62_2360x1640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>A New Micro-State</h2><p>With window resizing comes the ability for users to create tiny windows with micro states. It&#8217;s something that isn&#8217;t quite a widget, but certainly goes smaller than your typical iPhone experience. The minimum size I found (running the iPad A16 simulator) was <strong>375 x 486</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xwLl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xwLl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png 424w, https://substackcdn.com/image/fetch/$s_!xwLl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png 848w, https://substackcdn.com/image/fetch/$s_!xwLl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png 1272w, https://substackcdn.com/image/fetch/$s_!xwLl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xwLl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png" width="339" height="375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:375,&quot;width&quot;:339,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:108760,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xwLl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png 424w, https://substackcdn.com/image/fetch/$s_!xwLl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png 848w, https://substackcdn.com/image/fetch/$s_!xwLl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png 1272w, https://substackcdn.com/image/fetch/$s_!xwLl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d0f110-7a7e-4269-ada2-e82e10834914_339x375.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This could work for many experiences, but I would imagine there are some that already find it difficult to work on iPhone SE screens (568 x 320). That kind of micro-state might already break UI on an iPhone SE &#8212; and shrinking below that risks hiding essential UI or causing accessibility breakdowns.</p><p>Unfortunately, setting a minimum frame for a view does not seem to be respected. Here, I set a minimum height and width on my Content View and resizing completely breaks the experience:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zNgC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zNgC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif 424w, https://substackcdn.com/image/fetch/$s_!zNgC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif 848w, https://substackcdn.com/image/fetch/$s_!zNgC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif 1272w, https://substackcdn.com/image/fetch/$s_!zNgC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zNgC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif" width="500" height="348.4375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/decf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:223,&quot;width&quot;:320,&quot;resizeWidth&quot;:500,&quot;bytes&quot;:1083951,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zNgC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif 424w, https://substackcdn.com/image/fetch/$s_!zNgC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif 848w, https://substackcdn.com/image/fetch/$s_!zNgC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif 1272w, https://substackcdn.com/image/fetch/$s_!zNgC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdecf3bcd-b4ee-4c7b-be32-a731d14eaf4c_320x223.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>And <code>defaultSize</code> and <code>windowResizability</code> don't really do anything.</p><h2>Possible Micro-State Solution: Cover Page</h2><p>If your experience really cannot work in certain frames, you could consider using a Cover Page to block access to the experience. Here, I state that whenever the window goes below a certain size (the SE dimensions), show a Text instead:</p><pre><code><code>ViewThatFits {
    ContentView()
        .frame(minWidth: 320, maxWidth: .infinity, minHeight: 568, maxHeight: .infinity)
        
    Text("Please resize the window")
        .font(.headline)
}
</code></code></pre><p>The result gets the job done, but if your app allows for it then a more robust cover experience would certainly work, as well:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UjpZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UjpZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif 424w, https://substackcdn.com/image/fetch/$s_!UjpZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif 848w, https://substackcdn.com/image/fetch/$s_!UjpZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif 1272w, https://substackcdn.com/image/fetch/$s_!UjpZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UjpZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif" width="349" height="500.80717488789236" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:320,&quot;width&quot;:223,&quot;resizeWidth&quot;:349,&quot;bytes&quot;:1539370,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UjpZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif 424w, https://substackcdn.com/image/fetch/$s_!UjpZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif 848w, https://substackcdn.com/image/fetch/$s_!UjpZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif 1272w, https://substackcdn.com/image/fetch/$s_!UjpZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc0d20c3-a5aa-45fc-af1d-711431d4f90c_223x320.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Prepare for Foldable iPhone Through Window Testing</h2><p>Apple seems to be full steam ahead with releasing a foldable iPhone next year (<a href="https://www.macrumors.com/2025/07/10/foldable-iphone-display-production-begins/">production on the display for it has begun</a>). The obvious scenario is that your app may exist on double the normal screen width. Using iPad's Windowing, we could probably emulate what this experience could look like (repost from above, but for contextual emphasis):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!08HM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!08HM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!08HM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!08HM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!08HM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!08HM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png" width="630" height="437.88461538461536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1012,&quot;width&quot;:1456,&quot;resizeWidth&quot;:630,&quot;bytes&quot;:2676901,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/168240081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!08HM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png 424w, https://substackcdn.com/image/fetch/$s_!08HM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png 848w, https://substackcdn.com/image/fetch/$s_!08HM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!08HM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04568d17-c8ac-4005-b26b-998c2c3ecec8_2360x1640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There's a chance split view could appear on the foldable (think landscape on a Pro Max), or perhaps a unique split view with a sidebar more appropriate for a foldable phone factor.</p><h2>Embrace the Windows of Opportunity</h2><p>Windowing for iPadOS really is the natural next step in the evolution of the platform. While it could certainly mean your development team has its work cut out for it to account for the new system, users will certainly appreciate it.</p><p>You can also look at windowing as fitting in with the new Liquid Glass design system. Think about how windows &#8220;fluidly&#8221; resize and how Apple would love for your experiences to &#8220;fluidly&#8221; adjust. In the updated <a href="http://developer.apple.com/design/human-interface-guidelines">Human Interface Guidelines</a>, there are three new design principles: Hierarchy, Harmony, and Consistency. The latter states:</p><blockquote><p><em>&#8220;Adopt platform conventions to maintain a consistent design that continuously adapts across window sizes and displays.&#8221; </em>- Apple&#8217;s Human Interface Guidelines</p></blockquote><p>That&#8217;s as straight-forward as it can get. We&#8217;re in the Liquid Glass era now: the sooner we embrace its principles, the better we can modernize our apps for our users!</p><div><hr></div><p>Need help with <strong>Liquid Glass</strong>? Consider a <strong><a href="https://captainswiftui.substack.com/about#&#167;consult-with-the-captain">Consultation with the Captain</a></strong>!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/about#&#167;consult-with-the-captain&quot;,&quot;text&quot;:&quot;Learn About Liquid Glass Consultations&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/about#&#167;consult-with-the-captain"><span>Learn About Liquid Glass Consultations</span></a></p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Finding Deeper Meaning in Liquid Glass Search]]></title><description><![CDATA[How Apple has aligned search with where they believe the future of application design is going]]></description><link>https://captainswiftui.substack.com/p/finding-deeper-meaning-in-liquid</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/finding-deeper-meaning-in-liquid</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Sun, 06 Jul 2025 11:43:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XJoc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XJoc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XJoc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XJoc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XJoc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XJoc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XJoc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1248585,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/167540481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XJoc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XJoc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XJoc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XJoc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c64af94-9aef-4d15-b18e-b5c7e143c639_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Search: one of the biggest features of all technology, as well as one of the most significant quests in life. Think about it: searching for (in no particular order) the right opportunity, the right someone, the right information, the right plumber, and (occasionally) Spock.</p><p>As we enter deeper into the Age of AI, search remains a core component of yet another technological era. Digital search expectations have gone beyond expecting a list of SEO-optimized websites and/or a wikipedia article. We expect interactive, collaborative, and expansive responses. In short, we're not just looking for answers anymore, but discoveries.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Where Liquid Glass (LG) takes search fits with what (I believe) is the true goal of Apple's new design system: ushering apps into the new age. I've talked about how Apple can passive aggressively push devs into a more modern (if not opinionated) direction (see my article on <a href="https://captainswiftui.substack.com/p/translations-concurrency-pattern">Translation</a>. LG is all about that in many different doses, and search just happens to be one of the most glaring ones of all.</p><h2>The Two Pattern That Have Shifted, At Large</h2><p>Apple shared in <a href="https://developer.apple.com/videos/play/wwdc2025/323">Build a SwiftUI app with the new design</a> that two main patterns have shifted in LG. First:</p><blockquote><p>"Search in the toolbar (on iOS) places the field at the bottom of the screen, within easy reach.<br>And on iPad and Mac, it appears in the top-trailing position of the toolbar."</p><p>- <a href="https://developer.apple.com/videos/play/wwdc2025/323/?time=684">Build a SwiftUI app with the new design</a></p></blockquote><p>Simple change here, but a good one to note. In both scenarios, search gets its due by being placed in the expected, optimal utility location on screen.</p><p>The second change is narrowed to iOS, but is no doubt one of the biggest navigational shifts in LG:</p><blockquote><p>"The second pattern is to treat it as a dedicated page in a multi-tab app."</p><p>- <a href="https://developer.apple.com/videos/play/wwdc2025/323/?time=698">Build a SwiftUI app with the new design</a></p></blockquote><p>This single statement doesn't quite capture the impact of what's changed, so let's unpack a bit.</p><h2>The Brilliant Audacity of iOS's TabView Search</h2><p>The TabView in LG has already caused quite a stir. If you've read my initial exploration of the new TabView in my <a href="https://captainswiftui.substack.com/p/keeping-score-with-liquid-glass-and">MLB Tracker POC</a>, then you know how excited I've been by the potential it unlocks (particularly if starting a fresh app). In review:</p><ul><li><p>Hovers over content, affording more visibility of the content behind it</p></li><li><p>Can have minimizing behavior set to provide even more real estate to the TabItem being displayed</p></li><li><p>Allows for a bottom accessory that can reside above or inline with TabView</p></li></ul><p>Calling for search to be a dedicated page adds to LG's opinionated design system while also scaling with the idea that search goes beyond answer seeking and into discovery. This new space is a central spot where users can specify what they initially were looking for as well as explore the wealth of other information and experiences your app offers.</p><p>As developers, the question we&#8217;re answering is &#8220;What do I need to show the user <em>before</em> they even search?&#8221;.</p><h3>Apple&#8217;s Guiding API</h3><p>The way Apple drives this discoverable search concept is through the API, itself. When it comes to adding a <code>TabItem</code> with the <code>search</code> role, it actually requires you to provide 3 other things in order to actually appear in the new LG fashion:</p><ol><li><p>The <code>searchable</code> modifier - ensuring that search is still the key feature</p></li><li><p>Contents of the <code>TabItem</code> wrapped in a <code>NavigationStack</code> - insinuating that search should lead users on paths, not just destinations</p></li><li><p>Make it the last "fitting" tab without triggering the "More" tab - if you have more destinations for your users to navigate to than can fit in the <code>TabView</code>, you'll need to relinquish "auto-collating" them into the "More" tab and, instead, assume the responsibility of making them explorable from the dedicated page (we'll see an example of this in a bit)</p></li></ol><p>In code, this looks something like this:</p><pre><code><code>@State private var searchText: String = ""
...
TabView {
    Tab("Scores", systemImage: "baseball.diamond.bases") {
        GameListView()
    }    
    Tab("Standings", systemImage: "figure.baseball") {
        StandingsView()
    }
    Tab("Scout", systemImage: "magnifyingglass", role: .search) {
        NavigationStack {
            ScoutView()
        }
    }
}
.searchable(text: $searchText)
</code></code></pre><p>In a sense, Apple would love for you to adopt the new search, but forces you to make it a conscious decision. The reward is the foundation is laid out and ready for exploring.</p><h2>Exploring Examples from Apple</h2><p>Apple has already implemented the new dedicated search page in a few of their iOS 26 apps, namely News and Health. In both of the iOS 18 version of the apps, there was already a dedicated tab providing a traditional implementation of the search/discoverability pattern:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!B51Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B51Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png 424w, https://substackcdn.com/image/fetch/$s_!B51Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png 848w, https://substackcdn.com/image/fetch/$s_!B51Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png 1272w, https://substackcdn.com/image/fetch/$s_!B51Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B51Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png" width="568" height="480.1325966850829" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1224,&quot;width&quot;:1448,&quot;resizeWidth&quot;:568,&quot;bytes&quot;:286531,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/167540481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!B51Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png 424w, https://substackcdn.com/image/fetch/$s_!B51Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png 848w, https://substackcdn.com/image/fetch/$s_!B51Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png 1272w, https://substackcdn.com/image/fetch/$s_!B51Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffae4ec8b-9794-4311-b1ff-ff7a92ee7965_1448x1224.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">News and Health in iOS18</figcaption></figure></div><p>In iOS 26, those pages call for special attention with tabs that stand out:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5qza!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5qza!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png 424w, https://substackcdn.com/image/fetch/$s_!5qza!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png 848w, https://substackcdn.com/image/fetch/$s_!5qza!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png 1272w, https://substackcdn.com/image/fetch/$s_!5qza!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5qza!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png" width="1062" height="318" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:318,&quot;width&quot;:1062,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:140612,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/167540481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5qza!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png 424w, https://substackcdn.com/image/fetch/$s_!5qza!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png 848w, https://substackcdn.com/image/fetch/$s_!5qza!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png 1272w, https://substackcdn.com/image/fetch/$s_!5qza!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46e6d1ae-19ef-476b-bca7-05173b11a236_1062x318.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The TabView in News and Health on iOS26</figcaption></figure></div><p>And when we enter those pages, the underlying views look very similar, but search is given better access from the bottom of the screen while also giving back screen real estate (instead of <code>TabView</code> and the search bar being present, the two are combined floating over the content).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6RDn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6RDn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png 424w, https://substackcdn.com/image/fetch/$s_!6RDn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png 848w, https://substackcdn.com/image/fetch/$s_!6RDn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png 1272w, https://substackcdn.com/image/fetch/$s_!6RDn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6RDn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png" width="569" height="480.9779005524862" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/291666ba-a604-4043-8876-9b46739e5702_1448x1224.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1224,&quot;width&quot;:1448,&quot;resizeWidth&quot;:569,&quot;bytes&quot;:319665,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/167540481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6RDn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png 424w, https://substackcdn.com/image/fetch/$s_!6RDn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png 848w, https://substackcdn.com/image/fetch/$s_!6RDn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png 1272w, https://substackcdn.com/image/fetch/$s_!6RDn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291666ba-a604-4043-8876-9b46739e5702_1448x1224.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The Search pages for News and Health on iOS26</figcaption></figure></div><h2>Scouting Out Search in MLB Tracker</h2><p>To see what it would look like in the <a href="https://github.com/dbolella/MLBTracker">MLB Tracker</a>, I added the necessary components I listed earlier and asked Xcode's AI Assistant to create a demo "ScoutView" (sticking with baseball terms). The result fit right in with the app's theme and even begun to inspire future features that could be added to the tracker:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rNQC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rNQC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!rNQC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!rNQC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!rNQC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rNQC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif" width="229" height="496.8135593220339" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aca0493c-f395-400d-8445-2c7b5734456a_295x640.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:295,&quot;resizeWidth&quot;:229,&quot;bytes&quot;:2228449,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/167540481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rNQC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!rNQC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!rNQC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!rNQC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faca0493c-f395-400d-8445-2c7b5734456a_295x640.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Search fits right in on the MLB Tracker</figcaption></figure></div><h2>What To Look For In The Future</h2><p>This "spotlighting" Apple is providing for search in Liquid Glass intuitively elevates its role in UI to match where search and discovery is headed. With Apple slowly prepping more AI features while also calling for more Intents, Snippets and Widgets, I believe that &#8220;discoveries&#8221; are to lead us to &#8220;enriched&#8221;results.</p><p>In the MLB Tracker, searching a player could navigate me to the &#8220;Players&#8221; feature in the app, but maybe it also shows a snippet of the player as I&#8217;m continuing to type. Something that highlights that it&#8217;s a player result alongside the information and highlights I was hoping to see, with the option to dig deeper upon interacting with the snippet.</p><p>And then maybe this sets up my app data and &#8220;micro-experiences&#8221; to be discoverable beyond my app. Perhaps by Siri, other apps, AI models&#8230; who knows.</p><p>But for now, at least, it starts in your app. All in the form of a tab that represents that the treasures you&#8217;ve prepared for your users are ready to be used and explored.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Thoughts on Liquid Glass as a New Design System]]></title><description><![CDATA[The Captain talks through the impact of the new design system during Office Hours]]></description><link>https://captainswiftui.substack.com/p/thoughts-on-liquid-glass-as-a-new</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/thoughts-on-liquid-glass-as-a-new</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Tue, 01 Jul 2025 11:19:41 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/166914417/7ede4b990562e551f92d00fdfe0d32bb.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<p>During the latest session of Office Hours, I shared my thoughts on Liquid Glass as Apple&#8217;s New Design System and how all devs need to take it seriously.</p><p>If you would like to join the next session of Office Hours, consider subscribing!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Summarizing Scores with Foundation Models, #Playground, and Xcode AI]]></title><description><![CDATA[Apple's AI offerings for developers are knocking it out of the park, both on and off device]]></description><link>https://captainswiftui.substack.com/p/summarizing-scores-with-foundation</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/summarizing-scores-with-foundation</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Wed, 25 Jun 2025 11:02:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!frk9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!frk9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!frk9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!frk9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!frk9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!frk9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!frk9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1509252,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/166772981?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!frk9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!frk9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!frk9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!frk9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f94c-6226-444e-9dea-12f8d65cf484_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>After WWDC25, I kept building on my mocked-out <a href="https://captainswiftui.substack.com/p/keeping-score-with-liquid-glass-and">MLB Tracker app</a> &#8212; this time exploring Apple&#8217;s new AI tools: <a href="https://developer.apple.com/documentation/foundationmodels">Foundation Models</a> and Xcode 26&#8217;s built-in assistant. I also took the new <code>#Playground</code><a href="https://developer.apple.com/documentation/Xcode/running-code-snippets-using-the-playground-macro"> macro</a> for a spin. This post is part dev log, part proof of concept, and full of baseball energy.</p><p>To follow along, check out the latest code on <a href="https://github.com/dbolella/MLBTracker">Github</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>Foundation Models is a Game Changer</h2><p>Since the app already has 2 main screens (one for game scores and another for team standings) complete with mock data, the simplest generative AI feature I could think of was a summarizer. Yes, both screens are served visually well through Lists. But what if I was driving or out for a run and preferred hearing an up-to-date summary of where things stood in the MLB?</p><p>Starting with game scores first, I first created a function to print the game data neatly to a String and created my first Playground to see the result:</p><pre><code><code>#Playground {
    print(printBaseballGamesDetails(generateMockGames()))
}
</code></code></pre><p>Tremendously impressed already, but more on that later...</p><p>Then, I created a new class called <code>ScoresSummarizer</code>. In there, I added a static base prompt that would make the request with detailed instructions for what I wanted. To help me write the prompt, I got real meta with it and asked ChatGPT in my browser to make me a perfect prompt (see full prompt on <a href="https://github.com/dbolella/MLBTracker/blob/main/MLBTracker/Summarizers/ScoresSummarizer.swift">Github</a>).</p><p>Then I added a static function that would combine the printed data with the prompt, generate the model session, trigger the combined prompt, and return the response:</p><pre><code><code>static func summarizeGameScores(_ games: [BaseballGame]) async throws -&gt; String {
    let gameData = await printBaseballGamesDetails(games)
    let combinedPrompt = basePrompt + gameData
    let session = LanguageModelSession()
    let response = try await session.respond(to: combinedPrompt).content
    return response
}
</code></code></pre><p>To test it out, I created another Playground closure and checked the results. Already I can foresee my future code bases riddled with Playgrounds:</p><pre><code><code>#Playground {
    print(try! await ScoresSummarizer.summarizeGameScores(generateMockGames()))
}
</code></code></pre><p>While not instantaneous (I run a Mac Mini M4 w/ 16 GB RAM. Come at me, bro) I was pleasantly surprised by the response generated:</p><blockquote><p><strong>Meanwhile:</strong><br>Bottom of the 8th in Atlanta &#8212; Braves trailing 8-3 against the Diamondbacks!<br><strong>Over in:</strong><br>Bottom of the 8th in Cincinnati &#8212; Reds clinging to a 4-3 lead over the Blue Jays!<br><strong>Also tonight:</strong><br>Top of the 7th in Oakland &#8212; Athletics take an early 9-7 lead over the Cubs!<br><strong>Meanwhile:</strong><br>Bottom of the 9th in Milwaukee &#8212; Guardians edge out Brewers 1-0!<br><strong>Also tonight:</strong><br>Bottom of the 9th in San Francisco &#8212; Giants bounce back with an 8-1 victory over the Dodgers!<br>...</p></blockquote><p>Ground-breaking sports journalism? No. But it's taken my data and turned it into something more readable and, in particular, easy to listen to. And all this without using <code>Generable</code>, <code>Guide</code>, or <code>Tool</code>. Just a basic prompt and response.</p><h3>Displaying the Results</h3><p>To show off the summary in the app, I first added a <code>task</code> to my Scores view that triggers generating the summary. I also set a new <code>@State</code> property to collect the response and another to track that the summary has been generated.</p><pre><code><code>@State private var summaryReady = false
@State private var generatedSummary: String?

...

.task {
    do {
        generatedSummary = try await StandingsSummarizer.summarizeStandings()
        summaryReady = true
    } catch {
        // Handle error if needed
    }
}
</code></code></pre><p>Once generated, a button with a baseball SF Symbol appears in the top toolbar (Liquid Glass style, of course). Once tapped, a <code>sheet</code> appears displaying the response:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d0i4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d0i4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!d0i4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!d0i4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!d0i4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d0i4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif" width="320" height="694.2372881355932" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:295,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3197482,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/166772981?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d0i4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!d0i4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!d0i4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!d0i4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47ada04b-2a59-4e91-9bac-5e2fcece534f_295x640.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Speaking the Results</h3><p>In the GIF above, you'll see I also added a "Read Summary Aloud" button. When tapped, I trigger a read out of the summary using <code>AVSpeechUtterance</code> and <code>AVSpeechSynthesizer</code>:</p><pre><code><code>private func readSummary() {
    guard let summary = generatedSummary else { return }
    let utterance = AVSpeechUtterance(string: summary)
    utterance.rate = 0.57
    utterance.pitchMultiplier = 0.8
    utterance.postUtteranceDelay = 0.2
    utterance.volume = 0.8
    let voice = AVSpeechSynthesisVoice(language: "en-GB")
    utterance.voice = voice
    let synthesizer = AVSpeechSynthesizer()
    synthesizer.speak(utterance)
}
</code></code></pre><p>This was a new feature, but it highlights how easily we can generate content that can power other features in iOS. Combining summaries and speech can really change the "hands-free" game!</p><h2>Cleaning Things Up with Xcode AI</h2><p>I took all the code added for the Scores Summarizing (model code and UI additions) and copied it over for the Standings feature. The only difference (besides changing some names) was generating a different prompt for the Standings summary. But beyond that, the structure between the Game Score and Standings screens are almost identical.</p><p>Which led me to an idea. I asked Xcode AI to look at the similarities between the two Screens and create a new base Template View for reuse purposes. The result was detailed steps listed out on how it would approach the task, then the generation of the Template View, and a refactoring of the feature views to utilize the new template.</p><p>I hit run and, predictably (though still amazingly) the app was functionally the same. It was really satisfying to not only watch my POC code undergo some healthy gut rearranging, but for it to work on the first go.</p><h2>Stealing Bases with Xcode AI</h2><p>While impressed, I wasn't done experimenting with AI just yet. During the opening sessions, they showed off drawing a UI by hand, uploading it to the chat, and having it spit out impressively matching SwiftUI.</p><p>This felt like the big one to test out. And so, I imagined that, when a user taps on the live score in the tabview bottom accessory, a sheet would appear with a more detailed overview of a game's current status. Breaking out the ancient tools known as paper and pen, I drew a fantastic rendering of my vision:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Duji!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Duji!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Duji!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Duji!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Duji!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Duji!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg" width="384" height="476.83516483516485" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1808,&quot;width&quot;:1456,&quot;resizeWidth&quot;:384,&quot;bytes&quot;:1837590,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/166772981?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Duji!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Duji!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Duji!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Duji!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F592d97e4-810b-4b7e-a47a-eac441541680_2268x2816.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I snapped a pic, AirDropped to my machine, and dropped it into the chat with the prompt "when a user taps the tabview bottom accessory, a sheet should appear with the current games details displayed using the attached drawn UI. Create this view and attach it to the tabview bottom accessory". Within seconds, it delivered something that, in all honesty, beat my expectations:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cgMV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cgMV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!cgMV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!cgMV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!cgMV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cgMV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif" width="320" height="694.2372881355932" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ebe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:295,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3443535,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/166772981?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cgMV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif 424w, https://substackcdn.com/image/fetch/$s_!cgMV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif 848w, https://substackcdn.com/image/fetch/$s_!cgMV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif 1272w, https://substackcdn.com/image/fetch/$s_!cgMV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febe37615-7f2b-4d9f-8d32-c945e75ab7c3_295x640.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It's far from perfect, for sure. But in terms of translating a drawing I made in under a 30 seconds (see squiggles in the game summary section), I was particularly impressed that:</p><ul><li><p>It added relevant mock text to the summary section instead of the squiggles</p></li><li><p>It nailed the three dots for the outs</p></li><li><p>It suggested and implemented medium and large detents</p></li><li><p>It built a baseball diamond (albeit 45 degrees off)</p></li></ul><p>With some small UI fixes (diamond angle and padding on top in medium detent), I have a UI that I can begin to hook up to data in no time (probably seconds with just another prompt).</p><h2>AI for MVP?</h2><p>This time around I got to mess with AI features on-device and off. For all the speculation around AI, Apple Intelligence, and WWDC, at the very least developers won big this year.</p><h3>On-device</h3><p>Foundation Models are gonna help Apple developers usher in a new era of AI powered apps (mind you, I did a basic prompt without even getting into <code>Generable</code>, <code>Guide</code>, or <code>Tool</code>). Yes, we've already seen quite a bit of AI-powered apps already, for sure. But on-device generation brings with it privacy, security, immediacy, unlimited uses (seemingly), and network-less access.</p><p>Sure it's capabilities are limited compared to server-driven solutions. We're still at the dawn of this new era, one where individuals and organizations are becoming more aware and concerned about the loss of privacy and control of the information. As on-device models become increasingly better alongside ever-evolving supporting hardware, I guarantee its value will scale with it exponentially.</p><h3>Off-device</h3><p>As for Xcode's AI features, in spite of the concerns I just mentioned about server-driven solutions, it's really fun and a huge game changer for Apple developers. Having worked with other solutions like Cursor, Claude, and Copilot (just realized they all start with C's), I'm positive there are pros and cons to each.</p><p>Apple has the advantage of providing a baked in solution that could integrate with their IDE in ways no other solution could. With what I saw during sessions and experienced on my machine (so far), I believe they proved that point really well on the first shot. That makes me hopeful that we could potentially see really incredible stuff over the next few WWDC's. Just imagine bringing that power over to Instruments and supercharging app optimization and performance.</p><h2>Seventh-inning Stretch</h2><p>As for my exploration into WWDC goodies, this has only been a taste so far. I've been digging deep into Liquid Glass, understanding more about what's changed, and letting it sync in that Apple means it when they say it's a new design system.</p><p>As the summer continues, I'll be sharing more expansions to this little MLB Tracker app as well as focused articles on specific topics. So stand up, stretch those legs, grab some cracker jacks, and stay tuned!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Keeping Score with Liquid Glass & TabView Bottom Accessory]]></title><description><![CDATA[Putting this year's new feature's up to bat with the new Liquid Glass TabView]]></description><link>https://captainswiftui.substack.com/p/keeping-score-with-liquid-glass-and</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/keeping-score-with-liquid-glass-and</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Fri, 13 Jun 2025 20:34:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KQVw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KQVw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KQVw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!KQVw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!KQVw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!KQVw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KQVw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:791258,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165892408?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KQVw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!KQVw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!KQVw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!KQVw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52dcbddc-94d7-4ff9-8f88-fd581f5e7abc_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This year's WWDC has really got me thinking about what's next for Apple development. Liquid Glass ushers in a new era of mobile design and, with it, some really radical UX perspective shifts. SwiftUI has matured to a point where (alongside a redesign) the primary focus feels like its shifted in supporting and improving performance. And then there's Foundational Models, introducing on-device intelligence to both the consumer and developer masses.</p><p>While I've been enjoying watching the sessions... I needed to get my hands dirty. So I downloaded Xcode 26, (accidentally) installed macOS Tahoe on my personal machine, and got to work creating a base iOS app that will be my testing grounds of sorts. Probably for the next few articles.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>For this starter article, we'll try using Xcode 26's new AI tools and Liquid Glass's new TabView. And let me tell you... I think Apple knocked it out of the park with these.</p><h2>Starting Line-up: Creating a Demo MLB App</h2><p>To test things out, I built a simple (mocked out) baseball scores app. A TabView will drive out two main pages: scores and standings. Scores will simple list out games and there scores while standings will list out team standings based on League and Division.</p><p>This will give us an opportunity to experiment with the new Liquid Glass <code>TabView</code>. I'm extremely curious about how much real-estate we're really gaining by the glass look and floating design, plus the new <a href="https://developer.apple.com/documentation/swiftui/view/tabbarminimizebehavior(_:)">minimizing behaviors</a> we can apply. To make it even more worthwhile, there'll also be the new <a href="https://developer.apple.com/documentation/swiftui/view/tabviewbottomaccessory(content:)">bottom accessory</a> to the TabView that will show the score of a "live" game.</p><h2>Play ball!</h2><p>That's already a tall order and I didn't want to take up too much time away from watching sessions. Therefore, I enlisted the new intelligence features in Xcode 26 to help build the base of the app.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/dbolella/MLBTracker&quot;,&quot;text&quot;:&quot;Source Code on Github&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/dbolella/MLBTracker"><span>Source Code on Github</span></a></p><p>I opened the chat window and explained the two main views and asked for the data models I would need. I then asked it to create basic UI's for both based on the descriptions I gave earlier. The results were not too shabby:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5vG_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5vG_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png 424w, https://substackcdn.com/image/fetch/$s_!5vG_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png 848w, https://substackcdn.com/image/fetch/$s_!5vG_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png 1272w, https://substackcdn.com/image/fetch/$s_!5vG_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5vG_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png" width="544" height="464" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:696,&quot;width&quot;:816,&quot;resizeWidth&quot;:544,&quot;bytes&quot;:157977,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165892408?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5vG_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png 424w, https://substackcdn.com/image/fetch/$s_!5vG_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png 848w, https://substackcdn.com/image/fetch/$s_!5vG_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png 1272w, https://substackcdn.com/image/fetch/$s_!5vG_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee304b76-e185-4ac2-b6c0-79620e55f0d9_816x696.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can see that the TabView is no longer a bar but the floating dock we&#8217;ve seen in visionOS. You also can tell that, while you can see the List behind the tabs, there&#8217;s a frosted look obscuring the details.</p><p>For the sake of focusing this article on the new things, I'm not gonna post the snippets for the stuff up to this point. But, if you are curious, you can view the code on <a href="https://github.com/dbolella/MLBTracker">Github</a>.</p><h2>Scouter's Eye: Creating a Live Score Accessory</h2><p>Imagine your checking the days scores and standings but there's a game going on right now and you wanna stay on top of it's progress. The new TabView Bottom Accessory honestly feels like a perfect use of this feature.</p><p>Now, remember, I'm just playing with mock/static data, but I created a super simple View that has a baseball indicator symbol, the abbreviations and scores for both teams, and what inning it is. Enough to track what's going on.</p><pre><code><code>.tabViewBottomAccessory {
    HStack {
        Image(systemName: "baseball.diamond.bases.outs.indicator")
        Text("\(MLBTeam.yankees.abbreviation) 4 - 3 \(MLBTeam.redSox.abbreviation)")
            .bold()
        Image(systemName: "arrow.up")
            .font(.caption)
        Text("7")
    }
}
</code></code></pre><p>The result looked great:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KiQh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KiQh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png 424w, https://substackcdn.com/image/fetch/$s_!KiQh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png 848w, https://substackcdn.com/image/fetch/$s_!KiQh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png 1272w, https://substackcdn.com/image/fetch/$s_!KiQh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KiQh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png" width="323" height="702.2437810945273" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2622,&quot;width&quot;:1206,&quot;resizeWidth&quot;:323,&quot;bytes&quot;:445018,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165892408?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KiQh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png 424w, https://substackcdn.com/image/fetch/$s_!KiQh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png 848w, https://substackcdn.com/image/fetch/$s_!KiQh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png 1272w, https://substackcdn.com/image/fetch/$s_!KiQh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac3300ad-b96b-42f5-ba0e-a1e411696876_1206x2622.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Then I took it a step further by adding <code>.tabBarMinimizeBehavior(.onScrollDown)</code>. And boy did I really, really like the results:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LkuZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LkuZ!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif 424w, https://substackcdn.com/image/fetch/$s_!LkuZ!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif 848w, https://substackcdn.com/image/fetch/$s_!LkuZ!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif 1272w, https://substackcdn.com/image/fetch/$s_!LkuZ!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LkuZ!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif" width="312" height="678.3111111111111" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1174,&quot;width&quot;:540,&quot;resizeWidth&quot;:312,&quot;bytes&quot;:9158688,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165892408?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LkuZ!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif 424w, https://substackcdn.com/image/fetch/$s_!LkuZ!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif 848w, https://substackcdn.com/image/fetch/$s_!LkuZ!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif 1272w, https://substackcdn.com/image/fetch/$s_!LkuZ!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7f66865-0b8e-44c9-9e8e-e375a0abd914_540x1174.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I <strong>love</strong> this new accessory plus minimize behavior! That is just one of the coolest things I've seen this year from WWDC. The accessory, itself, is minimalist, yet informative while persisting across tabs (notice in the GIF that I switch tabs and the accessory stays in place). It can easily be swapped out for different views (either by user choice or based on some context) and can be made tappable by placing a button or gesture.</p><p>To me, it sets a hopeful tone about what Liquid Glass could be trying to achieve. Let me explain.</p><h2>Approaching the Mound</h2><p>Think about it: The TabView <em>literally</em> eats up a portion of your screen's real estate displaying the same icons and text almost permanently. When you think about it, it's such an incredibly dead waste of space just to ensure a basic navigation. Yes, we could have added Badges, but the View has remained mostly unaltered for ages.</p><p>Just enabling the new minimizing behavior (without an accessory) is nice as it neatly folds and packs the tabs to the bottom corner, though it leaves a frosty covering in it's wake:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!c56x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c56x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png 424w, https://substackcdn.com/image/fetch/$s_!c56x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png 848w, https://substackcdn.com/image/fetch/$s_!c56x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png 1272w, https://substackcdn.com/image/fetch/$s_!c56x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c56x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png" width="310" height="673.9800995024875" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2622,&quot;width&quot;:1206,&quot;resizeWidth&quot;:310,&quot;bytes&quot;:478209,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165892408?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!c56x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png 424w, https://substackcdn.com/image/fetch/$s_!c56x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png 848w, https://substackcdn.com/image/fetch/$s_!c56x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png 1272w, https://substackcdn.com/image/fetch/$s_!c56x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c1ba485-ace2-413e-a419-6a5705e9eeaf_1206x2622.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>What takes this to a whole new level is that by enabling minimizing with an accessory, the tabs fold into that corner and the accessory then glides in to the now open space. Not only does this return back the space the accessory took above the TabView, but it makes the TabView space actually useful for more than just Tab Navigation!</p><h2>On Deck: Summaries with Foundation Models</h2><p>The next feature I want to test out is Foundation Models. I'd like to see how quickly I can get prompts and responses setup, so in my next article I'll create features that will summarize the list of scores and the current standings. Simple, but enough to lightly test how quickly we can add basic on-device AI features into our app (no networking, accounts, or web API's necessary). I also hope to use the new #Playground macro to test out my prompts in the IDE instead of re-running every time.</p><p>Looking forward to taking this demo app to the Big Leagues with you all!</p><p><em>Source code for this article can be found on <a href="https://github.com/dbolella/MLBTracker">Github</a>.</em></p><h2>Looking to Talk More WWDC? Join Office Hours on June 19th!</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GLLw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GLLw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GLLw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg" width="430" height="305.3796296296296" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:767,&quot;width&quot;:1080,&quot;resizeWidth&quot;:430,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GLLw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Looking to talk more about WWDC25 and all the other goodies we got this year? Ready to vent about and/or praise Liquid Glass? Wanna ask how I tested some of these things? We&#8217;ll talk about it all!</p><p>Join as a Paid Subscriber on July 19th at 11:00 am EDT! If you aren&#8217;t a member already, consider joining with a special discounted rate!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?coupon=e61c7588&amp;utm_content=165892408&quot;,&quot;text&quot;:&quot;Get 10% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?coupon=e61c7588&amp;utm_content=165892408"><span>Get 10% off for 1 year</span></a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[WWDC25 Keynote and PSOTU Impressions]]></title><description><![CDATA[The Captain's Initial Thoughts on What Apple Shared on Day 1]]></description><link>https://captainswiftui.substack.com/p/wwdc25-keynote-and-psotu-impressions</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/wwdc25-keynote-and-psotu-impressions</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Tue, 10 Jun 2025 02:11:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tr85!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tr85!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tr85!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tr85!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tr85!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tr85!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tr85!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:516605,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tr85!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tr85!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tr85!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tr85!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F496b2a97-57d9-4555-9361-6455be4c904a_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>WWDC25 is here and both the Keynote and Platform State of the Union are officially behind us. The time for (most) speculation is over as we enter a time of processing and (as we go through the week) digging deeper into all the new goodies.</p><p>Here's a rundown of some of things I took away from the sessions, with a promise to share more of my thoughts as the week progresses...</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>Rumors Were On Point</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cbWW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cbWW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png 424w, https://substackcdn.com/image/fetch/$s_!cbWW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png 848w, https://substackcdn.com/image/fetch/$s_!cbWW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png 1272w, https://substackcdn.com/image/fetch/$s_!cbWW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cbWW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png" width="348" height="338.43956043956047" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1416,&quot;width&quot;:1456,&quot;resizeWidth&quot;:348,&quot;bytes&quot;:1861048,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cbWW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png 424w, https://substackcdn.com/image/fetch/$s_!cbWW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png 848w, https://substackcdn.com/image/fetch/$s_!cbWW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png 1272w, https://substackcdn.com/image/fetch/$s_!cbWW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5520ea51-88c5-465f-9195-c1d3d7be2a37_1764x1716.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>Majority of rumors I had seen circulating proved to be true. In fact, it was almost too many things that proved to be true. It almost makes me wonder if they were leaked on purpose or, at the very least, guarded with lax security. But the things we now know were true leaks were:</p><ul><li><p>All OS versions (and Xcode) will adopt an annual-based versioning system (e.g. iOS 26 for 2026)</p></li><li><p>The UI re-design is official and dubbed Liquid Glass (see below for more details)</p></li><li><p>Apple Intelligence was discussed at length, but (as expected) Apple punted most new features until "later this year"</p></li><li><p>Conversely, Apple did announce the new Foundation Models Framework and significant App Intents improvements, exposing apps to more AI services and tools both on-device and off (see below for more details)</p></li><li><p>The gap between iPadOS and macOS narrowed significantly more than in past years with new Windowing and File systems</p></li></ul><p>While rumors gave us possible insight, it was interesting to see these come to life during the talks.</p><h2>Liquid Glass</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tCVG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tCVG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png 424w, https://substackcdn.com/image/fetch/$s_!tCVG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png 848w, https://substackcdn.com/image/fetch/$s_!tCVG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png 1272w, https://substackcdn.com/image/fetch/$s_!tCVG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tCVG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png" width="1456" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:544067,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tCVG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png 424w, https://substackcdn.com/image/fetch/$s_!tCVG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png 848w, https://substackcdn.com/image/fetch/$s_!tCVG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png 1272w, https://substackcdn.com/image/fetch/$s_!tCVG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f30cc46-4b27-4e75-8fad-0b13c451809e_2456x674.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>It wasn't much of a surprise that the new UI design system would be glass-based. Seeing it in it's glory, however, was pretty awesome. Keeping it high-level for now, what I'll say is that almost every native component has been altered. And there are a ton of navigation and micro-interactions changed or added.</p><p>Apple shared that the guiding design principles at the core of the redesign were Hierarchy, Harmony, and Consistency (you know, HHC). At first glance, they seem to have achieved that very well and in intuitive ways.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KeBz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KeBz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png 424w, https://substackcdn.com/image/fetch/$s_!KeBz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png 848w, https://substackcdn.com/image/fetch/$s_!KeBz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png 1272w, https://substackcdn.com/image/fetch/$s_!KeBz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KeBz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1358144,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KeBz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png 424w, https://substackcdn.com/image/fetch/$s_!KeBz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png 848w, https://substackcdn.com/image/fetch/$s_!KeBz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png 1272w, https://substackcdn.com/image/fetch/$s_!KeBz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eb79a31-06d8-4e4e-924b-4baffae8d648_1712x1142.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>What is abundantly clear is that every development team will have its work cut out for it this year. While it all looks very cool and impressive, it will certainly send many teams into a frenzy trying to figure out if it breaks any existing UX.</p><p>Apple offered an approach that the developers should consider when tackling the redesign:</p><ul><li><p>Recompile: the re-design will automatically take affect once recompiled</p></li><li><p>Refine and Tailor: in other words, refactor and adjust accordingly to restore UX flow and harmony</p></li><li><p>Liquid Glass Effects: once stable, consider diving deeper into Liquid Glasses new features and applying them to your app</p></li></ul><p>Documentation on <a href="https://developer.apple.com/documentation/technologyoverviews/adopting-liquid-glass">Adopting Liquid Glass</a> is already posted and is a must-read.</p><h2>SwiftUI: No Longer The New Kid on the Block</h2><p>When you look at the <a href="https://developer.apple.com/documentation/updates/swiftui">SwiftUI Update</a> page and compare the June 2025 list to June 2024, it is <em>significantly</em> smaller. I'm sure this is disappointing for many devs who had specific SwiftUI items on their wishlists this year.</p><p>Given the scope of Liquid Glass, I'm really not that surprised. Apple made it abundantly clear that a lot has changed with the redesign and given that we still have a week of sessions ahead of us, I don't think we should underestimate how that may alter our wishlists, as well. I mean, just look at this "subset" of areas Apple said was altered:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ins1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ins1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png 424w, https://substackcdn.com/image/fetch/$s_!Ins1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png 848w, https://substackcdn.com/image/fetch/$s_!Ins1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png 1272w, https://substackcdn.com/image/fetch/$s_!Ins1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ins1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png" width="1456" height="814" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:814,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1486978,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ins1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png 424w, https://substackcdn.com/image/fetch/$s_!Ins1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png 848w, https://substackcdn.com/image/fetch/$s_!Ins1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png 1272w, https://substackcdn.com/image/fetch/$s_!Ins1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c2982cc-ce83-494f-9fd6-561b6208f761_3584x2003.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>For better or worse, we will need to reexamine majority of components, modifiers, interactions, and customizations to understand what problems still exist, have been solved, or have emerged.</p><h3>Performance and Instrument Gains</h3><p>Apple stated that SwiftUI performance has improved, specifically for macOS which has now adopted idle pre-fetching. It was specifically called out that Lists and Tables (note: not Scrollviews or other containers) have been optimized, with macOS claiming Lists with 100K items loading 6 times faster and updating 16 times faster.</p><p>While briefly mentioned, one of the most exciting new things to me was a new SwiftUI Performance Instrument which promises to dig into specific/suspected views that could be hindering performance. This is a <em>tremendous</em> win for SwiftUI as majority of performance issues I've come across are really the result of unoptimized code.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IhFk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IhFk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png 424w, https://substackcdn.com/image/fetch/$s_!IhFk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png 848w, https://substackcdn.com/image/fetch/$s_!IhFk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png 1272w, https://substackcdn.com/image/fetch/$s_!IhFk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IhFk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png" width="1456" height="814" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:814,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2612086,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IhFk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png 424w, https://substackcdn.com/image/fetch/$s_!IhFk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png 848w, https://substackcdn.com/image/fetch/$s_!IhFk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png 1272w, https://substackcdn.com/image/fetch/$s_!IhFk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa2976bb-2ebb-40e3-8009-25faf975144c_3584x2004.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><h2>Xcode: Pleasant Surprises</h2><p>In my pre-game article, I expressed that I didn't mind if no new AI tools or fancy features made it into Xcode this year, I just wanted more stability. I still want the stability, but I'd be lying if I said I wasn't excited about some of the new things they showed today.</p><p>The new AI Chat is not only an built-in solution to Copilot's extension, it takes it much further by having better interaction with the IDE, itself. Some key highlights were:</p><ul><li><p>Swapping generated snippets in and out</p></li><li><p>History Slider so you can revert or cherry pick generated changes you made over time</p></li><li><p>Automatic bug fixing (not that I believe it will work every time, but gets you a head start)</p></li><li><p>Sketch-to-SwiftUI</p></li><li><p>Ability to choose LLM Model/Service</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ESZj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ESZj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png 424w, https://substackcdn.com/image/fetch/$s_!ESZj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png 848w, https://substackcdn.com/image/fetch/$s_!ESZj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png 1272w, https://substackcdn.com/image/fetch/$s_!ESZj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ESZj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png" width="1456" height="847" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:847,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1746284,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ESZj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png 424w, https://substackcdn.com/image/fetch/$s_!ESZj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png 848w, https://substackcdn.com/image/fetch/$s_!ESZj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png 1272w, https://substackcdn.com/image/fetch/$s_!ESZj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ffaf63-cfcb-468c-b75a-86524c1ad300_2674x1556.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>I also cannot wait to use the new Playground macro. Think SwiftUI Preview but for your logical Swift code.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ihPo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ihPo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png 424w, https://substackcdn.com/image/fetch/$s_!ihPo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png 848w, https://substackcdn.com/image/fetch/$s_!ihPo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png 1272w, https://substackcdn.com/image/fetch/$s_!ihPo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ihPo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png" width="1456" height="910" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:910,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2608421,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ihPo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png 424w, https://substackcdn.com/image/fetch/$s_!ihPo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png 848w, https://substackcdn.com/image/fetch/$s_!ihPo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png 1272w, https://substackcdn.com/image/fetch/$s_!ihPo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f3cd4fc-1b2c-4710-adf8-e2e5b2b412fc_3584x2240.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>This could be a more direct way of testing your code and inspiring better unit tests.</p><h2>Foundation Models Framework</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JsoA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JsoA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png 424w, https://substackcdn.com/image/fetch/$s_!JsoA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png 848w, https://substackcdn.com/image/fetch/$s_!JsoA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png 1272w, https://substackcdn.com/image/fetch/$s_!JsoA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JsoA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png" width="1456" height="910" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:910,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:680194,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JsoA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png 424w, https://substackcdn.com/image/fetch/$s_!JsoA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png 848w, https://substackcdn.com/image/fetch/$s_!JsoA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png 1272w, https://substackcdn.com/image/fetch/$s_!JsoA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a597381-6e9f-4ae3-9026-90050c914ef9_3584x2240.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>The introduction of the new Foundation Models Framework was very exciting. It promises private, on-device generative capabilities for your apps (and Shortcuts). The framework looks really simple, yet powerful to adopt in your app.</p><p>Getting a model spun up and testable with the Playground macro takes only a few lines:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-UAC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-UAC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png 424w, https://substackcdn.com/image/fetch/$s_!-UAC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png 848w, https://substackcdn.com/image/fetch/$s_!-UAC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png 1272w, https://substackcdn.com/image/fetch/$s_!-UAC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-UAC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png" width="1456" height="910" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:910,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2608421,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-UAC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png 424w, https://substackcdn.com/image/fetch/$s_!-UAC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png 848w, https://substackcdn.com/image/fetch/$s_!-UAC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png 1272w, https://substackcdn.com/image/fetch/$s_!-UAC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2653e8-ec82-444c-a372-e8704b1431f1_3584x2240.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>Preparing structs to receive generated data is as simple as using the @Generable macro. Guiding responses is also made easy using the @Guide macro:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qm8G!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qm8G!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png 424w, https://substackcdn.com/image/fetch/$s_!Qm8G!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png 848w, https://substackcdn.com/image/fetch/$s_!Qm8G!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png 1272w, https://substackcdn.com/image/fetch/$s_!Qm8G!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qm8G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png" width="1456" height="910" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:910,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3257177,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/165595279?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Qm8G!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png 424w, https://substackcdn.com/image/fetch/$s_!Qm8G!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png 848w, https://substackcdn.com/image/fetch/$s_!Qm8G!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png 1272w, https://substackcdn.com/image/fetch/$s_!Qm8G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faacb610a-5cca-449b-8475-74d8b03e97cd_3584x2240.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image courtesy of Apple Inc.</figcaption></figure></div><p>I really can't wait to play with this new framework more. I'm sure there will be limitations, but on-device and privacy make this very appealing as a dev.</p><h2>And Many More...</h2><p>There were a number of other goodies that were announced that I look forward to diving into throughout the week (and, really, the rest of the summer). And I can't wait to write more articles and code exploring these topics beyond WWDC!</p><p>For now, the <a href="https://developer.apple.com/wwdc25/sessions-and-labs/">Sessions</a> page provides a list of our daily dose of introductions and walkthroughs. And new this year is a <a href="https://developer.apple.com/wwdc25/guides/">Guides</a> page. This collates the topics and sessions very neatly with great little summaries and list of related links. The best part is for categories such as <a href="https://developer.apple.com/documentation/updates/swift">Swift</a> and <a href="https://developer.apple.com/documentation/updates/swiftui">SwiftUI</a>, they also link to their respective update pages that list out their new associated documentation pages.</p><p>As promised, I will be posting a few more articles this week as sessions release and goods are digested more. And don't forget that next week will be a very special Office Hours where we'll discuss WWDC at-length!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Forming an Opinion on SwiftUI Forms]]></title><description><![CDATA[Filling in the Gaps on When to use SwiftUI's Form and When to Roll Your Own]]></description><link>https://captainswiftui.substack.com/p/forming-an-opinion-on-swiftui-forms</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/forming-an-opinion-on-swiftui-forms</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Tue, 27 May 2025 11:03:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!oS-O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oS-O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oS-O!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!oS-O!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!oS-O!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!oS-O!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oS-O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/be26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:720648,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/164414629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oS-O!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!oS-O!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!oS-O!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!oS-O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe26f41d-5a8f-4499-831b-791579e90804_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Not long ago, I took part in a healthy debate: Should an experience use SwiftUI&#8217;s built-in <code>Form</code>, or roll its own custom-styled container?</p><p>One camp argued in favor of <code>Form</code>, emphasizing that it follows Apple&#8217;s Human Interface Guidelines (HIG) by default. They believed that even if Apple updated its appearance in the future, sticking with <code>Form</code> would help us stay aligned with native platform conventions. Others weren&#8217;t so convinced &#8212; they wanted full control over styling, worried that relying on <code>Form</code> might lock us into a brittle or inflexible design path.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>As we explored both sides, something became clear: this wasn&#8217;t just a styling choice. It was an architectural and design philosophy decision. So in this article, we&#8217;re going to explore what <code>Form </code>actually does, why you might (or might not) want to use it, and what it really means to build a &#8220;form&#8221; in SwiftUI.</p><div><hr></div><h2>What <code>Form</code> Actually Does</h2><p>At its core, <code>Form</code> is just a <strong>container view</strong>&#8212; a specialized type of stylized <code>List </code>that Apple maintains and updates.</p><p>Wrapping your views in a <code>Form</code> applies platform-specific styling:</p><ul><li><p>On iOS, you get grouped rows, padding, and label alignment.</p></li><li><p>On macOS or visionOS, <code>Form </code>adapts to each platform&#8217;s standard form behavior.</p></li><li><p>In many cases, it will also group toggles, pickers, and text fields with proper accessibility behavior and spacing.</p></li></ul><p><code>Form</code> follows the Human Interface Guidelines (HIG) out of the box, making it easy to build views that "look right" without customizing spacing or alignment manually.</p><h3>Wait &#8212; what about <code>FormStyle</code>?</h3><p>SwiftUI does allow you to define a custom <code>FormStyle</code>. But after exploring that path, I found that <strong>creating a custom </strong><code>FormStyle</code><strong> feels nearly identical to just building your own container</strong> with a <code>VStack</code>, <code>ScrollView</code>, or even a custom <code>Layout</code>. You might gain some semantic clarity &#8212; e.g. denoting that &#8220;this block of UI is a form&#8221; &#8212; but in practice, <strong>you still need to handle layout and appearance yourself.</strong></p><h3>Experiment: Comparing a Custom FormStyle vs Custom Container</h3><p>I created a quick little experiment. I made a ridiculous custom <code>FormStyle</code>:</p><pre><code>struct CustomFormStyle: FormStyle {
    @MainActor @preconcurrency public func makeBody(configuration: CustomFormStyle.Configuration) -&gt; some View {
        ForEach(sections: configuration.content) { section in
            VStack {
                section.header
                    .font(.title)
                    .foregroundStyle(.purple)
                ForEach(subviews: section.content) { subview in
                    subview
                        .foregroundStyle(.pink)
                }
                section.footer
            }
            .background(Color.red)
        }
    }
}

extension FormStyle where Self == CustomFormStyle {
    @MainActor @preconcurrency internal static var custom: CustomFormStyle {
        .init()
    }
}</code></pre><p>I then created a custom container&#8230; with essentially the same code:</p><pre><code>struct CustomContainer&lt;Content: View&gt;: View {
    var content: Content
    
    var body: some View {
        ForEach(sections: content) { section in
            VStack {
                section.header
                    .font(.title)
                    .foregroundStyle(.purple)
                ForEach(subviews: section.content) { subview in
                    subview
                        .foregroundStyle(.pink)
                }
                section.footer
            }
            .background(Color.red)
        }
    }
}</code></pre><p>The result was that both custom implementations looked exactly the same, while using Grouped or Columns styles looked as expected:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wXFJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wXFJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png 424w, https://substackcdn.com/image/fetch/$s_!wXFJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png 848w, https://substackcdn.com/image/fetch/$s_!wXFJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png 1272w, https://substackcdn.com/image/fetch/$s_!wXFJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wXFJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png" width="233" height="505.49152542372883" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/83791c64-7c92-4283-b69d-2e34f820b882_295x640.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b31a7b96-d383-4c58-97aa-55b2caf2cabc_295x640.gif&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:295,&quot;resizeWidth&quot;:233,&quot;bytes&quot;:2073804,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/164414629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb31a7b96-d383-4c58-97aa-55b2caf2cabc_295x640.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wXFJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png 424w, https://substackcdn.com/image/fetch/$s_!wXFJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png 848w, https://substackcdn.com/image/fetch/$s_!wXFJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png 1272w, https://substackcdn.com/image/fetch/$s_!wXFJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83791c64-7c92-4283-b69d-2e34f820b882_295x640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In short: <code>Form</code> is a pre-styled container. Nothing more. If you don&#8217;t like Apple&#8217;s design decisions for forms, you may be better off just making your own.</p><blockquote><p><em>Join us June 19 @ 11am EDT for a special Office Hours: Post-WWDC Edition!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GLLw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GLLw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GLLw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg" width="510" height="362.19444444444446" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:767,&quot;width&quot;:1080,&quot;resizeWidth&quot;:510,&quot;bytes&quot;:316921,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/164414629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GLLw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GLLw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F798efac3-6589-4829-a64b-1b315578fa68_1080x767.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>We&#8217;ll be talking all about the WWDC goodies Apple brings this year and what they could mean for us devs! Join the Captain&#8217;s Crew as a Paid Subscriber to get access!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?coupon=e61c7588&amp;utm_content=164414629&quot;,&quot;text&quot;:&quot;Get 10% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?coupon=e61c7588&amp;utm_content=164414629"><span>Get 10% off for 1 year</span></a></p></blockquote><div><hr></div><h2>The Case <em>For</em> Using <code>Form</code></h2><p>There&#8217;s a reason Apple made <code>Form</code> in the first place: it streamlines a lot of common UI work and keeps your app aligned with system conventions.</p><p>Here are some good reasons to use it:</p><ul><li><p>&#9989; <strong>Adheres to HIG automatically</strong><br>You get consistent spacing, font sizes, and affordances with almost no effort.</p></li><li><p>&#9989; <strong>Future-proofing</strong><br>If Apple updates <code>Form</code>&#8217;s design in a future OS version, your views adapt for free &#8212; no manual restyling required.</p></li><li><p>&#9989; <strong>Less UI boilerplate</strong><br>You don&#8217;t need to micromanage padding or alignment across multiple sections and controls.</p></li><li><p>&#9989; <strong>Accessibility baked in</strong><br>Screen readers understand how to navigate grouped controls in a <code>Form</code>, and focus behavior is handled for you.</p></li><li><p>&#9989; <strong>Easy integration with system controls</strong><br>Pickers, toggles, and steppers drop in with ideal spacing and behavior.</p></li></ul><p>For many apps &#8212; especially settings pages or profile screens &#8212; these defaults are exactly what you want.</p><div><hr></div><h2>The Case <em>Against</em> Using <code>Form</code></h2><p>Despite its convenience, <code>Form</code> also comes with tradeoffs &#8212; especially for teams with strong design systems or highly customized layouts.</p><p>Some common drawbacks:</p><ul><li><p>&#10060; <strong>Limited styling flexibility</strong><br>If you want custom fonts, backgrounds, insets, or separators, you&#8217;ll find yourself fighting against <code>Form</code>&#8217;s default styling.</p></li><li><p>&#10060; <strong>Inconsistent behavior across platforms and OS versions</strong><br>What looks great on iOS 17 may feel odd on macOS or completely different on visionOS.</p></li><li><p>&#10060; <strong>Difficult to theme or brand</strong><br>Customizing <code>Form</code> to match your app&#8217;s unique look often involves painful workarounds.</p></li><li><p>&#10060; <strong>Hidden structure</strong><br>Because <code>Form</code> is backed by <code>List</code>, things like section spacing and background bleed may be controlled behind the scenes.</p></li><li><p>&#10060; <strong>You're locked into Apple&#8217;s opinion</strong><br>If you don&#8217;t agree with the HIG&#8217;s take on forms, you're essentially styling against the current.</p></li></ul><p>And, as I found while exploring <code>FormStyle</code>, the moment you start trying to "override" too much, <strong>you&#8217;re essentially re-implementing a container.</strong> At that point, it may be simpler &#8212; and more sustainable &#8212; to just write your own.</p><div><hr></div><h2>A Middle Path?</h2><p>Here&#8217;s the good news: this isn&#8217;t an either/or situation.</p><p>You can &#8212; and maybe should &#8212; use both approaches depending on context:</p><ul><li><p>Use <code>Form</code> for data entry views where HIG compliance is a benefit (e.g. settings, registration, feedback).</p></li><li><p>Use <strong>custom containers</strong> for marketing-heavy or brand-driven forms that require pixel-perfect control.</p></li><li><p>Consider wrapping fields in your own styled components like <code>FormSection</code>, <code>FormField</code>, or <code>FormGroup</code>, which provide the structure of a form without relying on <code>Form</code> itself.</p></li></ul><p>Ultimately, this is a <strong>design system decision</strong>, not just a SwiftUI one. If your team values native alignment, <code>Form</code> is a gift. If you&#8217;re chasing precision and consistency across platforms, rolling your own container might be the better path.</p><div><hr></div><h2>Final Thoughts</h2><p>SwiftUI&#8217;s <code>Form</code> isn&#8217;t magic &#8212; it&#8217;s just a container Apple maintains and styles for what it considers &#8220;form-like&#8221; interactions. And that&#8217;s not a bad thing. But it also means that <strong>if you disagree with Apple&#8217;s styling</strong>, you&#8217;re probably not looking to tweak <code>Form</code> &#8212; you&#8217;re looking to replace it.</p><p>My advice? Don&#8217;t fear the <code>Form</code>. But don&#8217;t treat it as sacred either. <strong>Know what it gives you, and what it costs.</strong>Then decide what&#8217;s best for your team and your users.</p><p>Happy forming.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[A Tale of Two Custom Container APIs]]></title><description><![CDATA[How the Public Custom Container Solution Stacks Up Against It's Shadowy, Private Counterpart in SwiftUI]]></description><link>https://captainswiftui.substack.com/p/a-tale-of-two-custom-container-apis</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/a-tale-of-two-custom-container-apis</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Tue, 13 May 2025 11:00:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!e-UN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!e-UN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!e-UN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!e-UN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!e-UN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!e-UN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!e-UN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1547493,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/163293984?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!e-UN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!e-UN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!e-UN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!e-UN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350ec652-de9b-4c60-a644-925f7d2b9f9a_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Container Views are the steel beams of SwiftUI. They provide the structure that holds all of its contents up, as well as for everything that gets built around it. Whether List, Stack, Group&#8230; all of these are core to declaratively composing experiences.</p><p>The concept of being able to actually create a custom container has been tossed around since SwiftUI was released. However, you could only go so far until you, most likely, needed to just rely on one of the given containers.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>That is, seemingly, until WWDC24's session called <a href="https://developer.apple.com/videos/play/wwdc2024/10146">Demystify SwiftUI Containers</a>, where they introduced new API's (<a href="https://developer.apple.com/documentation/swiftui/foreach/init(subviews:content:)">ForEach(subviews:) </a>and <a href="https://developer.apple.com/documentation/swiftui/group/init(subviews:transform:)">Group(subviews:)</a>) to finally gain access to the finer points of a container. All seemed exciting and well in the SwiftUI universe.</p><p>I decided to give this API a whirl and, at first, I was amazed at how simple and powerful it was to spin up a container in no time. I then decided to take it a step further and add some basic interactions. And that's when things took a turn...</p><h2>Ease at the Cost of Performance?</h2><p>As easy as these &#8220;container constructors&#8221; are, it was heartbreaking to hit a tremendous catch: I couldn&#8217;t make them reactive. At least, not in a performant manner.</p><p>Let me explain.</p><p>I experimented with Apple&#8217;s own sample from <a href="https://developer.apple.com/videos/play/wwdc2024/10146">Demystify SwiftUI Containers</a>. When you <a href="https://developer.apple.com/documentation/SwiftUI/Creating-custom-container-views">download the sample code</a>, there&#8217;s a v2 (just uses the ForEach) and a v5 (fully featured with Group and Sections). With both, I converted one of the sets of data into a State variable and created a tapGesture to add an item to that State.</p><p>My expectation was to see the new item appear, and I did.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tlfi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tlfi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png 424w, https://substackcdn.com/image/fetch/$s_!tlfi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png 848w, https://substackcdn.com/image/fetch/$s_!tlfi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png 1272w, https://substackcdn.com/image/fetch/$s_!tlfi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tlfi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png" width="652" height="489" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2064,&quot;width&quot;:2752,&quot;resizeWidth&quot;:652,&quot;bytes&quot;:834823,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/163293984?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93e18955-6c65-4179-bb7b-1d2e982e675b_2752x2064.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tlfi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png 424w, https://substackcdn.com/image/fetch/$s_!tlfi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png 848w, https://substackcdn.com/image/fetch/$s_!tlfi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png 1272w, https://substackcdn.com/image/fetch/$s_!tlfi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1be8018-ce3d-43fa-ac40-a91295672cfe_2752x2064.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Successfully modifying the example to add items on taps.</figcaption></figure></div><p>However&#8230; I also expected that, when monitoring with the SwiftUI Instrument, there would be evidence that only a new item was being drawn.</p><h3>What I Tried (And The Sad Results)</h3><p>I tested extensively. Meaning, I tried:</p><ul><li><p>Trying as-is</p></li><li><p>Adding <code>.id(...)</code> to each subview</p></li><li><p>Wrapping each subview in <code>EquatableView</code></p></li><li><p>Creating a custom <code>ContainerValue</code> to create unique id&#8217;s <em>within</em> the <code>ForEach</code></p></li></ul><p>None of these techniques reduced the redraw count. SwiftUI still diffed the <code>subviews</code> collection seemingly from scratch every time (meaning that despite any identifiable or equatable help I gave it, it was as if they didn&#8217;t exist). This resulted in a <strong>ton</strong> of draws per tap. Worse, with every tap, it consistently grew by 2 draws. This meant we were experiencing a linear growth in performance loss.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fwg1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fwg1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png 424w, https://substackcdn.com/image/fetch/$s_!fwg1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png 848w, https://substackcdn.com/image/fetch/$s_!fwg1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png 1272w, https://substackcdn.com/image/fetch/$s_!fwg1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fwg1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png" width="1456" height="867" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:867,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:294295,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/163293984?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fwg1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png 424w, https://substackcdn.com/image/fetch/$s_!fwg1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png 848w, https://substackcdn.com/image/fetch/$s_!fwg1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png 1272w, https://substackcdn.com/image/fetch/$s_!fwg1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5619cc46-30f6-46af-9d73-afc2e0e189f1_2206x1314.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I really wanted to see better results. I wanted to <em>believe</em> there were better results. And so I tried another experiment. One that involved breaking into one of the worst kept secrets in the SwiftUI API.</p><h2>Worst Kept Secret: VariadicView</h2><p>One of the coolest discoveries in SwiftUI was its secret API. Chris Eidhof shares a bit about this as a footer in <a href="https://chris.eidhof.nl/post/variadic-views/">one of his articles</a> where he quickly shares how we can go "spelunking into the <code>.swiftinterface</code>".</p><p>In the same article, we&#8217;re introduced to <code>VariadicView</code>. Before the <code>ForEach</code> and <code>Group</code> options, THIS was how custom containers were being built at the expert level.</p><p>And so, I had a thought: what if the worst kept secret was the best solution?</p><h3>Testing the Theory</h3><p>To test the theory, I took a trusted example of VariadicView from a trusted source: Jacob from <a href="https://blog.jacobstechtavern.com/">Jacob&#8217;s Tech Tavern</a>. He wrote a <a href="https://blog.jacobstechtavern.com/p/secret-swiftui">great article on VariadicView</a> that you should pause right now and go read (and then come right back). It seemed only right that I <a href="https://github.com/jacobsapps/_Secret_SwiftUI">pull his repo</a> as a base, attempt creating a converted version of his example, and then compare their performance using Instruments.</p><h3>Implementation Comparison</h3><p>What I did was pinpoint his Variadic implementation:</p><pre><code>struct ChatList&lt;Content: View&gt;: View {
    
    var content: Content

    init(@ViewBuilder content: () -&gt; Content) {
        self.content = content()
    }
    
    var body: some View {
        _VariadicView.Tree(ChatLayout()) {
            content
        }
    }
}

struct ChatLayout: _VariadicView_MultiViewRoot {
    
    func body(children: _VariadicView.Children) -&gt; some View {
        List {
            ForEach(children) { child in
                child
                    .inverted()
                    .listRowSeparator(.hidden)
            }
        }
        .listStyle(.plain)
        .inverted()
    }
}</code></pre><p>Then, I created what should represent the <code>ForEach</code> approach:</p><pre><code>struct ChatContainer&lt;Content: View&gt;: View {
    
    var content: Content

    init(@ViewBuilder content: () -&gt; Content) {
        self.content = content()
    }
    
    var body: some View {
        List {
            ForEach(subviews: content) { subview in
                subview
                    .inverted()
                    .listRowSeparator(.hidden)
            }
        }
        .listStyle(.plain)
        .inverted()
    }
}</code></pre><p>Comparing the code, it eliminates a few lines of code, making for a tighter implementation. It would have been great if the results matched.</p><p>However, when using <code>ForEach</code> (again, trying all the various ways), not only was it less performant (42 draws on tap as opposed to only 13 with Variadic)&#8230; the UX was negatively affected. Using Variadic, a new message would appear with a bit of an animation. Now, no animation.</p><h2>Resolution is the Problem?</h2><p>In the WWDC session on custom layouts, Apple clearly distinguishes between Declared Subviews and Resolved Subviews. The newer APIs, including subviews in layout and container contexts, work with the resolved version &#8212; that is, a system-generated representation after the SwiftUI engine computes the view hierarchy.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qyEn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qyEn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qyEn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:482973,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/163293984?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qyEn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5b9440-a184-4e78-9286-09e58b7e81ac_1280x720.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Screenshots courtesy of Apple Inc.</figcaption></figure></div><p>But here&#8217;s the catch: by calling them &#8220;resolved,&#8221; Apple hints at something deeper &#8212; any change to the underlying set of views requires a re-resolution. That includes adding or removing just a single item. And when resolution resets, the identity of each subview is essentially re-evaluated, leading to widespread redraws, even if most views are unchanged.</p><blockquote><h4>Key Takeaway</h4><p>When building custom containers in SwiftUI, <code>ForEach(subviews:)</code> may look like the right tool &#8212; but it doesn&#8217;t diff how you would expect. This leads to massive redraws as children are added or removed. Surprisingly, VariadicView is the only API I found that eliminates those redraws and scales cleanly with dynamic content.</p></blockquote><h2>Spread the Word: VariadicView is still the Custom (Dynamic) Container Solution</h2><p>This article was to be a victory lap for Custom Containers when added to my Trello board of topics. And, to be fair, it is a win if you are creating static container in your experience.</p><p>The fact of the matter is that there is a fundamental limitation to <code>ForEach(subviews:)</code> that is not immediately clear in the docs. Therefore, if you anticipate any interactive/dynamic aspects of your container, then perhaps turn to the secret ways of the shadows... er... <code>VariadicView</code>.</p><p><code>VariadicView</code> might not be the headline API in this story, but it&#8217;s still the hero behind the scenes.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Thoughts on App Delegate Deprecation]]></title><description><![CDATA[Listen to Captain SwiftUI&#8217;s thoughts on UIApplicationDelegate being deprecated and what that could mean for Apple&#8217;s strategy moving forward!]]></description><link>https://captainswiftui.substack.com/p/thoughts-on-app-delegate-deprecation</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/thoughts-on-app-delegate-deprecation</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Fri, 09 May 2025 13:31:30 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/163208127/59846539a0517827aecd6c037cfc85a5.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<p>Listen to Captain SwiftUI&#8217;s thoughts on UIApplicationDelegate being deprecated and what that could mean for Apple&#8217;s strategy moving forward!</p><p>Clip is from the first Office Hours on May 7. To join future sessions, upgrade to a paid subscription and join the crew!</p>]]></content:encoded></item><item><title><![CDATA[June 19th Office Hours Information!]]></title><description><![CDATA[Here's the details on how to join Office Hours: Post-WWDC Edition]]></description><link>https://captainswiftui.substack.com/p/may-7th-office-hours-information</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/may-7th-office-hours-information</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Wed, 07 May 2025 00:02:56 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!T0z3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T0z3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T0z3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png 424w, https://substackcdn.com/image/fetch/$s_!T0z3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png 848w, https://substackcdn.com/image/fetch/$s_!T0z3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!T0z3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T0z3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png" width="572" height="572" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1080,&quot;width&quot;:1080,&quot;resizeWidth&quot;:572,&quot;bytes&quot;:2723365,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/163015290?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T0z3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png 424w, https://substackcdn.com/image/fetch/$s_!T0z3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png 848w, https://substackcdn.com/image/fetch/$s_!T0z3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!T0z3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde94c150-bc11-4ce7-b629-ef9acfc9eb88_1080x1080.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Ahoy there! Tomorrow morning (<strong>June 19 @ 11am EDT</strong>) will be the second session of Office Hours! I cannot wait to discuss all the WWDC goodies and where we see things headed for SwiftUI!</p><p>If you are a paid subscriber, <strong>thank you</strong> for your support and I look forward to chatting with you! If you are not yet a paid subscriber, then <strong>consider joining</strong> and you will get access to tomorrow&#8217;s Office Hours, as well!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>We&#8217;ll start with brief introductions and a quick review of the events last week at <strong>WWDC</strong>. From there, I&#8217;ll open the floor to any questions or topics <strong>from the crew</strong>. Lastly, depending on time, I&#8217;ll dive into some topics I think are really interesting and kick start some conversation for the group.</p>
      <p>
          <a href="https://captainswiftui.substack.com/p/may-7th-office-hours-information">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[WWDC25 Pre-Game Analysis and Predictions]]></title><description><![CDATA[The Captain&#8217;s Take Heading Into The Happiest Week of an Apple Devs Year]]></description><link>https://captainswiftui.substack.com/p/wwdc25-pre-game-analysis-and-predictions</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/wwdc25-pre-game-analysis-and-predictions</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Mon, 05 May 2025 11:01:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!A5nP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!A5nP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!A5nP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!A5nP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!A5nP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!A5nP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!A5nP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:988844,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/162756439?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!A5nP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!A5nP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!A5nP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!A5nP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8ec8fb9-2c3d-416e-a843-c7f2bbbb8cb2_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We're roughly a month away from the most wonderful time of an Apple Dev's year: World Wide Developer Conference 2025. Every year we are bestowed goodies from Cupertino (and beyond) that often give us insight on where Apple is hoping to take the platforms and app development (ranging from glimpses to full-blown fire hose).</p><p>Some of my fellow writers have already shared their thoughts on and wishes for WWDC (shout out to <a href="https://swiftwithmajid.com/2025/04/08/wwdc25-wishes/">Majid</a>). I'm always trying to read the SwiftUI Sea, myself, and so here are some of my thoughts for this year.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>The Mood Going In</h2><p>This year feels... odd. There's already been strong rumors of things to come, doubts casted on what we'll see, and questions about where Apple actually envisions things are headed towards. That's awkward to say about the company that introduced the world to affordable PC's, revolutionized the music industry, radically changed the world with smart mobile devices, and so on.</p><p>But with <a href="https://www.macrumors.com/2024/12/31/vision-pro-may-be-out-of-production/">Vision Pro production being halted</a> (albeit possibly to prepare for a <a href="https://www.macrumors.com/2025/04/08/vision-pro-2-now-in-production/">Vision Pro 2</a>) and <a href="https://www.macrumors.com/2025/03/07/apple-intelligence-siri-features-delayed/">Apple Intelligence delays</a>, it's caused some concerns about Apple's ability to pivot to "the next big thing".</p><p>I don't believe this threatens the ecosystem Apple has built and, therefore, those already a partaker in it will most likely remain faithful (did that sound cult-of-mac like or what?). However, FOMO (fear of missing out) has already begun to creep in. And especially as a developer who uses Xcode daily.</p><h3>A Word on AI and Xcode</h3><p>I want to see more Apple Intelligence features across all platforms.</p><p>I want to see more Apple Intelligence in Xcode.</p><p>I want a more stable and improved Xc&#8230;</p><p>In all sincerity, I would of course love for many of the AI goodies we see with IDE&#8217;s like VS Code and Cursor make it&#8217;s way (natively) into Xcode. Having Apple provide the goods could give Xcode users more fine-tuned and relevant features. I&#8217;m already a fan of the auto-complete model, a step in the right direction.</p><p>Having said that, I&#8217;ve grown to use AI in one IDE, and then switch to Xcode to run/debug. If better AI in Xcode didn&#8217;t happen this year, I&#8217;d be fine with that.</p><p>Instead, I rather see Xcode become more stable and more robust, in general. Xcode really does provide some awesome features when you stop and take stock. But there are enough annoyances with Xcode that produce some of the negative/meh feelings I read and see in the community.</p><p>If I had to choose an MVP, I&#8217;d go with making Xcode as solid as possible.</p><h2>What We Can Strongly Expect</h2><p>Without a doubt, SwiftUI will continue to be the primary UI framework in majority of demos and announcements, just like we saw in WWDC 24. I also expect more frameworks to provide better interfacing with SwiftUI (similar to <a href="https://captainswiftui.substack.com/p/translations-concurrency-pattern?r=a1d9l">Translation</a> and <a href="https://blog.jacobstechtavern.com/p/swiftui-map-is-really-good-now?r=a1d9l&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=false">MapKit</a> in prior years).</p><p>But beyond those strong speculations, here are a few strong rumors worth keeping an eye out for...</p><h3>Overall Design Changes</h3><p>A strong rumor is that that iOS 19 will bring about some of the <a href="https://www.macrumors.com/2025/03/16/ios-19-big-design-changes/">biggest design changes</a> in over a decade. The goal is being reasoned that this will bring cross-platform cohesiveness much closer together, which is certainly a win. The inspiration seems to be many of the design decisions already found in VisionOS.</p><p>This rumor feels solid because we already saw some <a href="https://developer.apple.com/documentation/uikit/elevating-your-ipad-app-with-a-tab-bar-and-sidebar">VisionOS concepts creep into iPadOS 18 through the tab bar</a>. That particular change was a bit of an upheaval, so a more wide-scale makeover could enhance UX, but it may hurt developer backlogs this summer/fall.</p><h3>UIApplicationDelegate Deprecation</h3><p>According to Jeff Johnson's analysis, he presents compelling evidence that <a href="https://lapcatsoftware.com/articles/2025/4/5.html">UIApplicationDelegate will be deprecated in iOS19</a>. While deprecation does not mean mandatory change, this would still be a tremendous shift in iOS development. The <a href="https://developer.apple.com/documentation/uikit/uiapplicationdelegate">app delegate</a> has been the core for what feels like ages, so this news almost seems baffling.</p><p>The alternative Apple would push for is switching to <a href="https://developer.apple.com/documentation/uikit/uiscenedelegate">UISceneDelegate</a> (in fact, <a href="https://developer.apple.com/documentation/uikit/managing-your-app-s-life-cycle">Apple already suggests this for apps targeting iOS 13 onwards</a>). The full strategy has not been revealed (pending this rumor being true), but it may be worth exploring the (current) differences and possible meanings this will have on development.</p><blockquote><h4>UPDATE: CONFIRMED!</h4><p>Hours after this article was published (coincidence? I think not), <a href="https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle">Apple released a Tech Note</a> confirming the move from UIApplicationDelegate to UISceneDelegate.</p><p>The most intense quote came towards the beginning where they state: &#8220;<em>Soon, all <a href="https://developer.apple.com/documentation/uikit">UIKit</a> based apps will be required to adopt the scene-based life-cycle, after which your app won&#8217;t launch if you don&#8217;t.</em>&#8221;</p><p>This is striking because man believed the rumor would mean more ceremonial deprecation, not something mandatory. But the wording here is strong and clear: migrate or your app won&#8217;t launch&#8230;</p></blockquote><h3>Closing the Combine vs Observation Gap</h3><p>There is a swift evolution proposal currently wrapping up review (seemingly just in time for WWDC) called <a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0475-observed.md">SE-0475: Transactional Observation of Values</a>. When <a href="https://developer.apple.com/documentation/observation">Observation</a> was announced two years ago, it was exciting because it really embraced the concurrency/task-based/thread-safe future we all saw coming in Swift 6. Plus, it was shared that SwiftUI was already optimized to use Observation under the hood with more basic property wrappers.</p><p>One thing that felt awkward, though, was that programmatic tracking was primarily done using <a href="https://developer.apple.com/documentation/observation/withobservationtracking(_:onchange:)">withObservationTracking</a></p><pre><code><code>func printFlowers() { 
    withObservationTracking { 
        print(flower.name) 
    } onChange: { 
        print("Schedule printing.") 
    }
}
</code></code></pre><p>The proposal would essentially create an asynchronous sequence (note: <em>not</em> an AsyncSequence, which we'll come back to) using a new closure-initialized <code>Observed</code> type as well as "just-the-right-amount-of-magic" (their words, not mine).</p><pre><code><code>let flowerNames = Observed { flower.name }
</code></code></pre><p>Which would allow us to then write something more familiar like:</p><pre><code><code>for await name in flowerNames {
    print(name)
}
</code></code></pre><p>This also helps to better close the gap that Observation attempts to close between a Combine Publisher and AsyncSequence: the former supports broadcasting to multiple subscribers while the latter does not.</p><p>So now, when we attempt to do the following, all of the tasks will receive the same values from the same event that bore them:</p><pre><code><code>Task.detached {
  for await name in flowerNames {
    print("Task1: \(name)")
  }
}

Task.detached {
  for await name in flowerNames {
    print("Task2: \(name)")
  }
}
</code></code></pre><p>For those looking to move away from Combine and over to something more concurrency-based, this bolsters the argument for Observation.</p><blockquote><p><em>Want to talk more about this year&#8217;s upcoming WWDC? Join me live at Office Hours!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lPFB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lPFB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg" width="526" height="296.1185185185185" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:608,&quot;width&quot;:1080,&quot;resizeWidth&quot;:526,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lPFB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Open to all paid subscribers! Join at the button below and take advantage of a special promo discount!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=162756439&quot;,&quot;text&quot;:&quot;Get 10% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=162756439"><span>Get 10% off for 1 year</span></a></p></blockquote><h2>What I'd Like to See</h2><p>Just like I the one I write for Santa every December, it's now time for my WWDC wishlist. See, The Captain has been good all year and would love to see a few of these items under the OutlineGroup tree (note: even I rolled my eyes at how corny this paragraph turned out to be).</p><h3>Default Theming/Styling of Components</h3><p>Let's say I have a particular vision for how I want Button to look across my app. I could:</p><ul><li><p>Create a ButtonStyle, but that requires adding <code>.style</code> to each Button or surrounding Container</p></li><li><p>Create my own Button that wraps Button with my styling, but I might not be able to anticipate what initializers I need to account for (did you know there are 15 initializers for Button?)</p></li><li><p>Write a macro that automatically adds the modifiers I want to a specific component when recognized, but at the risk of blocking additional styling</p></li></ul><p>What would be great is for a way to simply declare style overrides in a centralized manner that could even be swappable.</p><h3>Recycling</h3><p>Considering all of Apple's green initiatives, it's surprising that SwiftUI doesn't offer more recycling (badum-tish). I want to echo one of Majid's wishes, as its one that so many SwiftUI devs have wanted (or have yet to realize they wanted): container views that allow for recycling.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L33j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L33j!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg 424w, https://substackcdn.com/image/fetch/$s_!L33j!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg 848w, https://substackcdn.com/image/fetch/$s_!L33j!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!L33j!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L33j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg" width="1009" height="566" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:566,&quot;width&quot;:1009,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:155576,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/162756439?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L33j!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg 424w, https://substackcdn.com/image/fetch/$s_!L33j!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg 848w, https://substackcdn.com/image/fetch/$s_!L33j!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!L33j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb57f38af-213e-4b5a-b439-79ee99a8cbcd_1009x566.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">This is what I wanna see! C&#8217;mon Craig!</figcaption></figure></div><p>There are custom built solutions out there, everything from wrapped UICollectionViews to more calculated, yet pure-SwiftUI solutions like <a href="https://nilcoalescing.com/blog/CustomLazyListInSwiftUI/">this one by Nil Coalescing</a>.</p><p>But, it would be great to see more native offerings. List was changed under the hood by Apple a few years ago to use UICollectionView, and it&#8217;s been a game changer. If Apple wants to continue to encourage prioritizing SwiftUI, this would be a great boost.</p><h2>Let The Hype Begin</h2><p>As we count down to the lights dimming on June 9th, I find myself riding that familiar mix of excitement and curiosity. Whether Apple delivers long-rumored hardware, surprises us with (actual) AI integrations, or simply refines what&#8217;s already great, WWDC always finds a way to mark a turning point&#8212;for our tools, our workflows, and our ambitions as developers.</p><p>I&#8217;m not just watching as an engineer&#8212;I&#8217;m watching as someone who still gets pumped when Craig takes the stage. And I know many of you feel the same. So what are you hoping for? What&#8217;s your boldest prediction? I&#8217;d love to hear it.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Underground Wrapper Scene]]></title><description><![CDATA[10 SwiftUI Property Wrappers and Values You Probably Don&#8217;t Know&#8230; But Should]]></description><link>https://captainswiftui.substack.com/p/the-underground-wrapper-scene</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/the-underground-wrapper-scene</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Mon, 28 Apr 2025 11:02:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!j0Ih!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j0Ih!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j0Ih!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!j0Ih!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!j0Ih!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!j0Ih!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j0Ih!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1088640,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/162147675?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!j0Ih!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!j0Ih!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!j0Ih!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!j0Ih!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0bbd600-1099-48a6-8737-090ef9e17211_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There I was, staring at my beautiful new experience written <em>entirely</em> in SwiftUI, months ahead of schedule as I promised (and gambled on). Feeling proud of myself, I went to show one of my teammates. They praised the work&#8230; and then asked how it looked in different dynamic sizes.</p><p>Uh oh&#8230;</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Much of the UI began to shrink and grow as we scaled from small to large. But the sub-containers that made up such a large part of the experience were set to a fixed height and width.</p><p>I quickly scrambled to find a solution, worrying that it would take another sprint to custom write something. But then, what&#8217;s this? <code>@ScaledMetric</code> you say? I quickly add it to my code.</p><p>That sense of aw and magic I had when I first used SwiftUI quickly washed over me as I watched these containers scale along with the overall experience. The fear of a lost sprint was squashed with a simple, mysterious <strong>property wrapper</strong>.</p><h3>Wrappers: Unsung Heroes of SwiftUI</h3><p>SwiftUI developers lean heavily on the classic property wrappers: <code>@State</code>, <code>@Binding</code>, <code>@ObservedObject</code>. But SwiftUI ships with <strong>a powerful cast of other property wrappers and wrapped values</strong> &#8212; some that solve complex problems with a single line of code.</p><p>This article is your curated guide to 10 wrappers and values that are often overlooked but deserve a spot in your toolkit.</p><p><em>Note: What do I mean by wrapped values? Towards the end of this list, you&#8217;ll see values that can be found in Environment. They are not wrappers, themselves. However, they felt at home on this list because of the similar help they offer experiences as well as to highlight some of the powerful values being kept &#8220;under wraps&#8221;.</em></p><h2>What Are Property Wrappers?</h2><p>Property wrappers in Swift are a powerful language feature that let you define reusable behaviors for how values are stored, computed, or observed. In SwiftUI, they&#8217;re everywhere: <code>@State</code>, <code>@Binding</code>, <code>@Environment</code>, and others all rely on this system.</p><p>At a high level, a property wrapper:</p><ul><li><p>Encapsulates a value (like a <code>Bool</code> or <code>String</code>)</p></li><li><p>Adds logic to how that value is read or written</p></li><li><p>Can expose additional projected values (like <code>$binding</code>)</p></li></ul><p>For example, <code>@State var isOn = false</code> actually wraps the value inside a <code>State&lt;Bool&gt;</code> struct, managing updates and triggering view re-renders when the value changes.</p><h3>Want to Make Your Own?</h3><p>If you&#8217;re curious about how custom wrappers are built, Apple has a concise guide here: <a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties/#Property-Wrappers">Swift Documentation &#8211; Property Wrappers</a></p><blockquote><p><em>Come join The Captain and the rest of the Captain&#8217;s Crew at Office Hours!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lPFB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lPFB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg" width="564" height="317.5111111111111" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:608,&quot;width&quot;:1080,&quot;resizeWidth&quot;:564,&quot;bytes&quot;:855017,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/161427640?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!lPFB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Open to all paid subscribers! Join at the button below and take advantage of a special promo discount!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=162147675&quot;,&quot;text&quot;:&quot;Get 10% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=162147675"><span>Get 10% off for 1 year</span></a></p></blockquote><h2>The Main Event</h2><p>And now it&#8217;s time to reveal some of the best Wrappers in the SwiftUI Game&#8230;</p><h3>1. <code>@ScaledMetric</code> &#8211; Auto-Scale UI for Dynamic Type</h3><p><strong>What it does:</strong><br>Automatically scales a numeric value (padding, size, etc.) based on the user's preferred text size.</p><pre><code><code>@ScaledMetric var size: CGFloat = 64

Image("avatar")
    .resizable()
    .frame(width: size, height: size)
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Adapts automatically to accessibility settings without manual recalculation.</p></li><li><p>Great for spacing, frames, and icons that need to feel "right" across small and large text settings.</p></li><li><p>Helps you avoid hardcoding fixed dimensions that break UX for accessibility users.</p></li></ul><p><strong>When to use it:</strong><br>When sizing UI elements that should grow naturally with Dynamic Type &#8212; like buttons, avatars, cards, or tap targets.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/scaledmetric">Learn more about @ScaledMetric</a></p><div><hr></div><h3>2. <code>@Namespace</code> &#8211; Enable Matched Geometry Transitions</h3><p><strong>What it does:</strong><br>Creates a transition context to morph views between states.</p><pre><code><code>@Namespace var animation

matchedGeometryEffect(id: "avatar", in: animation)
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Enables beautiful hero transitions where views fluidly animate across different screens.</p></li><li><p>Helps maintain spatial continuity for users (which improves UX dramatically).</p></li><li><p>Way less boilerplate than doing custom animations manually.</p></li></ul><p><strong>When to use it:</strong><br>Any time you're animating between screens or states &#8212; like photo galleries, card swipes, onboarding flows, or navigation transitions.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/namespace">Learn more about @Namespace</a></p><div><hr></div><h3>3. <code>@FocusedValue</code> &#8211; Share Values Across Focused Views</h3><p><strong>What it does:</strong><br>Exposes values based on the currently focused view. Perfect for input coordination.</p><pre><code><code>@FocusedValue(\.username) var username
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Great for building forms where data flows between fields without tightly coupling the views.</p></li><li><p>Lets you create smarter, context-aware toolbars or keyboards that change depending on focus.</p></li></ul><p><strong>When to use it:</strong><br>When multiple fields or child views need to share or react to information based on the current focus &#8212; like dynamic toolbars or editing panels.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/focusedvalue">Learn more about @FocusedValue</a></p><div><hr></div><h3>4. <code>@GestureState</code> &#8211; Track Gesture Values</h3><p><strong>What it does:</strong><br>Tracks temporary state during a gesture and <strong>resets automatically</strong> after it ends.</p><pre><code><code>@GestureState private var isPressed = false

Circle()
    .scaleEffect(isPressed ? 1.2 : 1.0)
    .gesture(
        LongPressGesture()
            .updating($isPressed) { value, state, _ in state = value }
    )
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>No need to manually reset gesture state &#8212; SwiftUI cleans it up for you.</p></li><li><p>Makes it easy to animate elements during gestures like drags, long-presses, or swipes.</p></li></ul><p><strong>When to use it:</strong><br>Anytime you want temporary visual feedback during a user interaction &#8212; like highlighting, scaling, or revealing hidden options while dragging.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/gesturestate">Learn more about @GestureState</a></p><div><hr></div><h3>5. <code>@FocusState</code> &#8211; Control Input Focus Declaratively</h3><p><strong>What it does:</strong><br>Manage keyboard focus between multiple fields using simple state binding.</p><pre><code><code>@FocusState private var focusedField: Field?

TextField("Username", text: $username)
    .focused($focusedField, equals: .username)
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Cleaner and safer than UIKit&#8217;s messy <code>becomeFirstResponder()</code>/<code>resignFirstResponder()</code>.</p></li><li><p>Crucial for building great, intuitive SwiftUI forms, especially for keyboard users.</p></li></ul><p><strong>When to use it:</strong><br>Whenever you want to control or track which field is active &#8212; like auto-advancing fields, validating on focus loss, or dismissing keyboards cleanly.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/focusstate">Learn more about @FocusState</a></p><div><hr></div><h3>6. <code>@AppStorage</code> &#8211; Persist User Defaults with Zero Boilerplate</h3><p><strong>What it does:</strong><br>Binds directly to <code>UserDefaults</code> with reactive updates.</p><pre><code><code>@AppStorage("isDarkMode") var isDarkMode = false
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>You get persistence <strong>and</strong> view updates automatically.</p></li><li><p>No more manually syncing between UI state and stored settings.</p></li></ul><p><strong>When to use it:</strong><br>For lightweight user preferences &#8212; like theme modes, onboarding completion, toggle switches, or any user-specific flags.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/appstorage">Learn more about @AppStorage</a></p><div><hr></div><h3>7. <code>@SceneStorage</code> &#8211; Persist View State Across Sessions</h3><p><strong>What it does:</strong><br>Restores view state like scroll position, tab selection, or input text.</p><pre><code><code>@SceneStorage("draftText") var text: String = ""
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Keeps your app feeling seamless even when a scene or window is closed and reopened.</p></li><li><p>Essential for iPad multitasking and Stage Manager where apps frequently suspend and resume.</p></li></ul><p><strong>When to use it:</strong><br>For view-local state that should survive temporary app interruptions &#8212; like scroll positions, selected tabs, or form drafts.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/scenestorage">Learn more about @SceneStorage</a></p><div><hr></div><h3>8. <code>@Environment(\.dynamicTypeSize)</code> &#8211; Read Current Type Size</h3><p><strong>What it does:</strong><br>Gives you access to the current Dynamic Type size setting (like <code>.large</code>, <code>.accessibility5</code>).</p><pre><code><code>@Environment(\.dynamicTypeSize) var typeSize

if typeSize.isAccessibilitySize {
    CompactLayout()
} else {
    RegularLayout()
}
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Lets you <strong>adapt layouts</strong>, not just text size, for accessibility.</p></li><li><p>You can build UIs that totally rethink structure at large text sizes.</p></li></ul><p><strong>When to use it:</strong><br>When you need major layout shifts for users with accessibility text sizes &#8212; like stacking content vertically or increasing tap target spacing.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/environmentvalues/dynamictypesize">Learn more about EnvironmentValues/dynamicTypeSize</a></p><div><hr></div><h3>9. <code>@Environment(\.horizontalSizeClass)</code> &#8211; Build Responsive Layouts</h3><p><strong>What it does:</strong><br>Lets you respond to size class changes (compact vs regular).</p><pre><code><code>@Environment(\.horizontalSizeClass) var sizeClass

if sizeClass == .compact {
    VerticalLayout()
} else {
    HorizontalLayout()
}
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Helps you create adaptive interfaces that work on iPhone, iPad, and Mac seamlessly.</p></li><li><p>Vital for Split View, Stage Manager, and dynamic resizing scenarios.</p></li></ul><p><strong>When to use it:</strong><br>Whenever you want a view to layout differently based on device, orientation, or window size.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/environmentvalues/horizontalsizeclass">Learn more about EnvironmentValues/horizontalSizeClass</a></p><div><hr></div><h3>10. <code>@Environment(\.isEnabled)</code> &#8211; Respect System Interactivity</h3><p><strong>What it does:</strong><br>Check whether your view or container is enabled or disabled.</p><pre><code><code>@Environment(\.isEnabled) var isEnabled

Text("Label")
    .opacity(isEnabled ? 1 : 0.5)
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Lets you customize how views behave when <code>.disabled()</code> is applied upstream.</p></li><li><p>You can build better, more consistent disabled states beyond just graying out a button.</p></li></ul><p><strong>When to use it:</strong><br>When creating custom components that need to respect (or override) enabled/disabled state from parent views.</p><p>&#128218; <a href="https://developer.apple.com/documentation/swiftui/environmentvalues/isenabled">Learn more about EnvironmentValues/isEnabled</a></p><h1>Wrap Up: These Wrappers Pull Serious Weight</h1><p>If you&#8217;re building modern, accessible, adaptive SwiftUI interfaces &#8212; don&#8217;t stop at @State. The wrappers above help you:</p><ul><li><p>Write cleaner code</p></li><li><p>Support accessibility out of the box</p></li><li><p>Handle persistence, focus, gestures, layout, and more</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Is There A Better AsyncButton?]]></title><description><![CDATA[Can We Tap Into Button's Full Async Potential... Or Are We Pressing Luck?]]></description><link>https://captainswiftui.substack.com/p/is-there-a-better-asyncbutton</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/is-there-a-better-asyncbutton</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Mon, 21 Apr 2025 10:02:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!iQDa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iQDa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iQDa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!iQDa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!iQDa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!iQDa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iQDa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:700960,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/161427640?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iQDa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!iQDa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!iQDa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!iQDa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe188134-36d0-4252-b2de-5f06b71748b6_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Button. The classic and (arguably) most basic interactive component of modern interfaces.</p><p>Yet, in the age of Swift 6 and concurrency, it can be baffling that Button&#8217;s evolution into an AsyncButton remains an open topic. When Googled, there are <em>numerous</em> implementations demo&#8217;d and written about.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>&#8220;But Captain,&#8221; you may be asking. &#8220;Is it worth sailing these seas if they&#8217;ve already been explored?&#8221;</p><p>&#8220;Aye,&#8221; said The Captain. &#8220;I do.&#8221;</p><h3>Charting Course</h3><p>In this article, we will explore three basic implementations of AsyncButton:</p><ol><li><p>AsyncGoogledButton - based on your typical Google answer</p></li><li><p>AsyncStructuredButton - an attempt to fix the Googled answer with some structure</p></li><li><p>AsyncTaskButton - an exploration into a more SwiftUI-based solution</p></li></ol><p>To test these out, I&#8217;ve created a simple macOS App (found on <a href="https://github.com/dbolella/AsyncButtonTest">Github</a>) that allows me to trigger an async (throwing) function that counts from 1 to 10, printing the current value every second.</p><pre><code>for i in 1...10 {
    try await Task.sleep(nanoseconds: 1000000000)
    print("Task Count: \(i)")
}</code></pre><p>The app looks like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xX2_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xX2_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png 424w, https://substackcdn.com/image/fetch/$s_!xX2_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png 848w, https://substackcdn.com/image/fetch/$s_!xX2_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png 1272w, https://substackcdn.com/image/fetch/$s_!xX2_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xX2_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png" width="1456" height="941" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:941,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:350782,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/161427640?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xX2_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png 424w, https://substackcdn.com/image/fetch/$s_!xX2_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png 848w, https://substackcdn.com/image/fetch/$s_!xX2_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png 1272w, https://substackcdn.com/image/fetch/$s_!xX2_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F723aa569-2f4e-452e-b07c-fb9eceb28aec_1684x1088.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It&#8217;s worth noting that for each type of AsyncButton, the buttons Task1 and Task2 switch the detail view on the right. This will be important to remember shortly.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/dbolella/AsyncButtonTest&quot;,&quot;text&quot;:&quot;Github Repo&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/dbolella/AsyncButtonTest"><span>Github Repo</span></a></p><h2>The (Potentially) Unstructured Problem With A Googled AsyncButton</h2><p>The typical answer on Google (or ChatGPT, if we want to be cheeky) is usually something like:</p><pre><code>Button(
    action: {
        Task {
            try await action()
        }
    },
    label: {
        label()
    }
)</code></pre><p>Perhaps, at a baseline, this is enough for many folks out there. However, what happens if the task is long running and the user decides they want to navigate away from the action?</p><p>In our testing app, I mentioned that for each implementation, we can switch between two detail views. If we start our task in the first view, and then switch to our second view:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8CbB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8CbB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif 424w, https://substackcdn.com/image/fetch/$s_!8CbB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif 848w, https://substackcdn.com/image/fetch/$s_!8CbB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif 1272w, https://substackcdn.com/image/fetch/$s_!8CbB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8CbB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif" width="731" height="597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b5993490-db2e-476a-9481-e8185401a920_731x597.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:597,&quot;width&quot;:731,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:498903,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/161427640?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8CbB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif 424w, https://substackcdn.com/image/fetch/$s_!8CbB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif 848w, https://substackcdn.com/image/fetch/$s_!8CbB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif 1272w, https://substackcdn.com/image/fetch/$s_!8CbB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5993490-db2e-476a-9481-e8185401a920_731x597.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We see that Task 1 continues to count. Even as we trigger Task 2, we see that Task 1 doesn&#8217;t stop until it hits 10. This is because we&#8217;ve triggered an <strong>unstructured task</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ucSR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ucSR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ucSR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ucSR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ucSR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ucSR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg" width="1400" height="700" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:118065,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/161427640?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ucSR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ucSR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ucSR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ucSR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F655d9272-193f-4f73-a2ce-9cdfa05a0858_1400x700.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Courtesy of Apple, Inc.</figcaption></figure></div><p><strong>Disclaimer</strong>: <em>maybe</em> it&#8217;s an ok scenario to have an unstructured task for your use case. If the task was to trigger a save operation, maybe we want to allow that to continue even after the user navigates away. To read more, about when you may want to use an unstructured task, check out <a href="https://www.donnywals.com/understanding-unstructured-and-detached-tasks-in-swift/">this article</a>.</p><p>However, there are certainly cases where we would want a continuous task to stop (e.g. we&#8217;re awaiting values that are only relevant to the screen where the task was triggered). Simply starting a Task from a synchronous context immediately releases control over the Task, itself, leaving you at the mercy of it&#8217;s own ability to manage its own lifespan.</p><blockquote><p><em>Come join The Captain and the rest of the Captain&#8217;s Crew at Office Hours!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lPFB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lPFB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg" width="564" height="317.5111111111111" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:608,&quot;width&quot;:1080,&quot;resizeWidth&quot;:564,&quot;bytes&quot;:855017,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/161427640?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lPFB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lPFB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F376f1c95-cddc-479e-b64f-93ce6f4c5c02_1080x608.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Open to all paid subscribers! Join at the button below and take advantage of a special promo discount!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=161427640&quot;,&quot;text&quot;:&quot;Get 10% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=161427640"><span>Get 10% off for 1 year</span></a></p></blockquote><h2>Adding Structure to AsyncButton&#8217;s Wild Nature</h2><p>Fortunately, adding view-dismissal-safety (or structure) to our AsyncButton is rather simple:</p><pre><code>@State var holdTask: Task&lt;Void, Error&gt;? = nil

...

Button(
    action: {
        holdTask = Task {
            try await action()
        }
    },
    label: {
        label()
    }
)
.onDisappear {
    holdTask?.cancel()
}</code></pre><p>We store the Task into a State property so that we can then reference it within onDisappear and cancel the task. This manually ties the life of the task to the appearance of the Button view.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Iw0x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Iw0x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif 424w, https://substackcdn.com/image/fetch/$s_!Iw0x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif 848w, https://substackcdn.com/image/fetch/$s_!Iw0x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif 1272w, https://substackcdn.com/image/fetch/$s_!Iw0x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Iw0x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif" width="731" height="597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96165f7a-1970-4745-b2b7-12427f836491_731x597.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:597,&quot;width&quot;:731,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:407715,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/161427640?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Iw0x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif 424w, https://substackcdn.com/image/fetch/$s_!Iw0x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif 848w, https://substackcdn.com/image/fetch/$s_!Iw0x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif 1272w, https://substackcdn.com/image/fetch/$s_!Iw0x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96165f7a-1970-4745-b2b7-12427f836491_731x597.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Note: This leads to possible enhancements where we expose the task <strong>outside</strong> of AsnycButton, possibly to expand our structured handling to other views or objects. For the sake of simplicity in this article, I&#8217;ll leave it to you to explore those options.</em></p><h2>One Step Further Using .task</h2><p>It&#8217;s great that we were able to add structure to AsyncButton by having it be tied to the appearance of it&#8217;s calling view. However, as Captain SwiftUI, I have to ask: what about using the .task modifier? After all, it promises to <em>automatically</em> tie the life of a task to the <em>life</em> of the calling view.</p><p>Let&#8217;s give this a go.</p><pre><code>@State private var isRunning = false

...

Button(action: {
    isRunning = true
}) {
    label()
}
.task(id: isRunning) {
    guard isRunning else { return }
    try? await action()
    isRunning = false
}</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DXla!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DXla!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif 424w, https://substackcdn.com/image/fetch/$s_!DXla!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif 848w, https://substackcdn.com/image/fetch/$s_!DXla!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif 1272w, https://substackcdn.com/image/fetch/$s_!DXla!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DXla!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif" width="731" height="597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:597,&quot;width&quot;:731,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:482222,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/161427640?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DXla!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif 424w, https://substackcdn.com/image/fetch/$s_!DXla!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif 848w, https://substackcdn.com/image/fetch/$s_!DXla!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif 1272w, https://substackcdn.com/image/fetch/$s_!DXla!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d4014d-4646-48ee-8ef8-244cadf41609_731x597.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Three less lines of code, no holding of a task property, and automatically tied to the <em>life of a view</em>. If this structured approach fits your use-case, then this seems like the <strong>ultimate</strong> answer.</p><h2>A Cautionary Tale of The Sneaky Error</h2><p>You might have noticed in the task implementation I used an optional <code>try?</code>. Because we&#8217;re passing in an async <em>throwable</em> closure, the task modifier actually complains about the throw not being handled. We didn&#8217;t get this complaint with the other implementations, but, out of curiosity&#8230; what happens if we to swap &#8220;?&#8221; for a &#8220;!&#8221;&#8230;</p><p>&#128680; <strong>MAYDAY! MAYDAY! &#128680;</strong></p><p>We get&#8230; a crash?!</p><pre><code>Fatal error: 'try!' expression unexpectedly raised an error: Swift.CancellationError()</code></pre><p>What the heck is a CancellationError and why are we getting this? As it turns out, CancellationError is thrown <a href="https://developer.apple.com/documentation/swift/cancellationerror">automatically when a task is cancelled</a>. Which means if we add an &#8220;!&#8221; in our structured implementation, we get the same crash over there, too.</p><p>This might not seem <em>entirely</em> relevant to our goals here, but it&#8217;s worth mentioning this because it&#8217;s one of the most overlooked Task-related errors. Your use-case may accept using a try? to simply handle this error. However, if you need more granular control, we can handle with a do-catch block:</p><pre><code>@State private var isRunning = false

...

Button(action: {
    isRunning = true
}) {
    label()
}
.task(id: isRunning) {
    guard isRunning else { return }
    <strong>do {
        try await action()
    } catch is CancellationError {
        print("Task was cancelled")
    } catch {
        if Task.isCancelled {
            print("Task was cancelled")
        } else {
            print(error.localizedDescription)
        }
    }</strong>
    isRunning = false
}</code></pre><p>This works for both the task modifier and structured approaches. It&#8217;s pointless for the unstructured approach because, well, there&#8217;s nothing to trigger a cancellation.</p><h2>Conclusion: We Can Build a Better Button (and A Better One, and A Better One&#8230;)</h2><p>We&#8217;ve explored previously traversed seas and pushed a little beyond, proving we can provide structure and better handling to AsyncButtons&#8230; <strong>if</strong> we need it.</p><p>That&#8217;s really at the crux of the AsyncButton topic, and probably why there is no native offering. There&#8217;s no few async contexts that can be easily managed by just one component.</p><p>I <em>love</em> the attempts, including <a href="https://github.com/Dean151/ButtonKit">this extensive and impressive one</a> by Thomas Durance (which he goes through in <a href="https://blog.thomasdurand.fr/story/2024-01-14-asynchronous-swiftui-buttons/">this article</a>). But ultimately, you may need to opt for building the AsyncButton that fits <em>your</em> needs best.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Captain SwiftUI is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Captain SwiftUI Levels Up ⚓️ Here’s What’s New]]></title><description><![CDATA[Office Hours, Consultations with The Captain, and Admiral&#8217;s Club]]></description><link>https://captainswiftui.substack.com/p/captain-swiftui-levels-up-heres-whats</link><guid isPermaLink="false">https://captainswiftui.substack.com/p/captain-swiftui-levels-up-heres-whats</guid><dc:creator><![CDATA[Danny Bolella]]></dc:creator><pubDate>Sun, 13 Apr 2025 11:02:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!k5qr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k5qr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k5qr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!k5qr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!k5qr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!k5qr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k5qr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1507839,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/160646163?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!k5qr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!k5qr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!k5qr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!k5qr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133a354f-7ae5-4915-9888-b2cfaeba9a1c_1456x1048.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Ahoy there! This is your Captain speaking&#8230;</p><p>I&#8217;ve been loving the community that&#8217;s been growing here and the positive feedback you all have been giving! That&#8217;s why I&#8217;m excited to announce expanded offerings and ways for the community to support those offerings.</p><p><em>Note: To be clear, my articles <strong>will remain free</strong>. I&#8217;m exploring ways that folks can choose to support my writing and some of these new offerings. If you are one of those folks interested, thank you and read on to learn more&#8230;</em></p><div><hr></div><p>With over 20 years of coding experience, more than a decade specializing in iOS and mobile development, and a track record of helping launch successful apps, I&#8217;m excited to offer <strong>office hours</strong> and <strong>consulting services</strong> to help developers and teams level up their iOS development skills.</p><p>Leading, teaching, and mentoring are passions of mine. It&#8217;s why I love being a Lead Software Engineer and why I take on side-projects such as co-authoring of <a href="https://www.amazon.com/Swift-Cookbook-recipes-developing-applications/dp/1803239581">The Swift Cookbook, Third Edition</a> and, of course, running <a href="https://captainswiftui.substack.com/">Captain SwiftUI</a>.</p><p>Whether you're an individual looking for career guidance or a team refining your mobile architecture, I&#8217;m here to help.</p><h1><strong>Office Hours for Crew Members (Paid Subscribers)</strong></h1><p>For those who have joined the Captain&#8217;s Crew as paid subscribers, I now host <strong>monthly office hours</strong>. Crew members can drop in with questions, discuss challenges, or get feedback on their projects.</p><h3><strong>What You Get</strong></h3><ul><li><p>Access to a <strong>monthly one-hour Q&amp;A session</strong></p></li><li><p>Direct insights from an experienced iOS engineer</p></li><li><p>Community-driven discussions on Swift, SwiftUI, and app architecture</p></li></ul><h3><strong>How to Join</strong></h3><ul><li><p><strong>Subscribe as a Paid Subscriber to Captain SwiftUI</strong></p></li><li><p><strong>Join the first live session on Wednesday, May 7 @ 8 pm EST</strong></p></li><li><p><strong>Regular schedule to be announced</strong> (recordings available for paid subscribers)</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=160646163&quot;,&quot;text&quot;:&quot;Get 10% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=160646163"><span>Get 10% off for 1 year</span></a></p><h1><strong>Consulting Services</strong></h1><p>Apart from paid subscriptions, I also provide <strong>tailored consulting sessions</strong> designed to solve your most pressing mobile development challenges. These sessions are ideal for:</p><ul><li><p>Code reviews and architecture guidance</p></li><li><p>Modularization and scalable iOS app structures</p></li><li><p>SwiftUI best practices and UI design principles</p></li><li><p>Performance optimization and debugging</p></li><li><p>Career advice and navigating the iOS job market</p></li></ul><h3><strong>How It Works</strong></h3><ul><li><p><strong>Inquiry Form:</strong> Fill out the <a href="https://docs.google.com/forms/d/e/1FAIpQLSfrc-k6ezeR5aFVJ2RUi_r5n_XWBDjVidu7d78ycVsHOlCwGg/viewform?usp=sharing">Inquiry Form</a> to provide details about your needs</p></li><li><p><strong>Personalized Follow-Up:</strong> I will review your request and reach out with pricing and next steps</p></li><li><p><strong>Scheduling &amp; Payment:</strong> Once aligned, I&#8217;ll provide a scheduling link and payment details</p></li></ul><p>Need ongoing support? I also offer <strong>retainer packages</strong> for teams looking for continuous mentorship.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://docs.google.com/forms/d/e/1FAIpQLSfrc-k6ezeR5aFVJ2RUi_r5n_XWBDjVidu7d78ycVsHOlCwGg/viewform?usp=sharing&quot;,&quot;text&quot;:&quot;Consult With The Captain!&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://docs.google.com/forms/d/e/1FAIpQLSfrc-k6ezeR5aFVJ2RUi_r5n_XWBDjVidu7d78ycVsHOlCwGg/viewform?usp=sharing"><span>Consult With The Captain!</span></a></p><h1><strong>Admiral&#8217;s Club</strong></h1><p>For those who want to take their support for Captain SwiftUI to the next level <em>and</em> take advantage of some special offers, I&#8217;m also offering a new Founder&#8217;s Tier called <strong>Admiral&#8217;s Club</strong>.</p><h3><strong>What You Get</strong></h3><ul><li><p>Access to Office Hours with higher priority given to your questions</p></li><li><p>Special 10% discount for Consulting Services</p></li></ul><h3><strong>How to Join</strong></h3><ul><li><p><strong>Subscribe as an Admiral&#8217;s Club Member to Captain SwiftUI</strong></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?"><span>Subscribe now</span></a></p><h1>Sponsored Ads</h1><p>Lastly, I plan to feature sponsored ads in future articles. This will help support keeping articles free at a baseline level. Substack, as a platform, doesn&#8217;t provide an ad template/component/embed option, which I think is <strong>great for readers</strong> as it means us writers can&#8217;t do anything super elaborate and intrusive.</p><p><strong>You&#8217;re here to read and (hopefully) learn. I want to respect that.</strong></p><p>To give you an idea of what these ads will look like, the following is an ad for an app a connection of mine recently released. Because I also happen to think it&#8217;s an awesome app that aims to give back and &#8220;leave this world a better place than we found it&#8221;, I asked if I could use promote it for the demo, free-of-charge. Please check it out!</p><blockquote><p><em>This article is brought to you by <a href="https://apps.apple.com/us/app/omil%C3%ADa/id1602156122">Omil&#237;a</a>:</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y3Of!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y3Of!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!Y3Of!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!Y3Of!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!Y3Of!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y3Of!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png" width="1200" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:335432,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://captainswiftui.substack.com/i/160646163?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y3Of!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!Y3Of!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!Y3Of!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!Y3Of!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6058a3c-f163-4273-ae92-f3ab41bd6f59_1200x600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Discover <a href="https://apps.apple.com/us/app/omil%C3%ADa/id1602156122">Omil&#237;a</a> &#8212; the speech and language app designed for individuals recovering from a stroke or traumatic brain injury. Explore interactive games to boost communication and cognitive skills in a fun, engaging and intuitive way!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://apps.apple.com/us/app/omil%C3%ADa/id1602156122&quot;,&quot;text&quot;:&quot;View Omil&#237;a in App Store&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://apps.apple.com/us/app/omil%C3%ADa/id1602156122"><span>View Omil&#237;a in App Store</span></a></p></blockquote><h3>Interested in Sponsoring?</h3><ul><li><p><strong>Email me at <a href="mailto:captainswiftui@gmail.com">captainswiftui@gmail.com</a></strong></p></li></ul><div><hr></div><h1><strong>Get Started</strong></h1><ul><li><p><strong>Become a paid subscriber with access to live office hours on May 7</strong>: <a href="https://captainswiftui.substack.com/promo">Subscribe Here</a></p></li><li><p><strong>Schedule a personalized Consultation with The Captain:</strong> <a href="https://docs.google.com/forms/d/e/1FAIpQLSfrc-k6ezeR5aFVJ2RUi_r5n_XWBDjVidu7d78ycVsHOlCwGg/viewform?usp=sharing">Inquiry Form</a></p></li><li><p><strong>Join the <a href="https://captainswiftui.substack.com/promo">Admiral&#8217;s Club</a> and get all the paid subscriber perks plus:</strong></p><ul><li><p>Priority at Office Hours</p></li><li><p>10% off consulting services</p></li></ul></li><li><p><strong>Sponsor this blog with an ad by emailing </strong><a href="mailto:captainswiftui@gmail.com">captainswiftui@gmail.com</a></p></li></ul><p>Question? Send me an e-mail!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=160646163&quot;,&quot;text&quot;:&quot;Get 10% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://captainswiftui.substack.com/subscribe?coupon=3a584c06&amp;utm_content=160646163"><span>Get 10% off for 1 year</span></a></p>]]></content:encoded></item></channel></rss>