Skip to content

Instantly share code, notes, and snippets.

@samhenrigold
Last active June 22, 2025 23:03
Show Gist options
  • Save samhenrigold/1e05a0dfa83ca953e7b99219e6bd9615 to your computer and use it in GitHub Desktop.
Save samhenrigold/1e05a0dfa83ca953e7b99219e6bd9615 to your computer and use it in GitHub Desktop.
WWDC25 SwiftUI group lab

(Summary generated by ChatGPT based on the automatic transcription. Transcript is attached to this Gist)

What’s your favorite new SwiftUI API this year?

Sommer:
The new rich text editor. It was a labor of love, worked cross-functionally with Foundation, TextKit, Core Text, UIKit, AppKit.

Nick:
Safe area bar. Combines concepts like scroll view insets, overlays—makes them easy and satisfying to use.

Anna:
NavigationLink indicator visibility. A popular developer request—exciting to bring it to the platform and back deploy it.

Taylor:
All the new APIs we didn’t introduce. Performance improvements, new designs, no new adoption burden—your app gets better “for free.”


When should developers use the new SwiftUI performance instrument?

Nick:
Use it when you notice a small change tanks performance. When you already have a mental model, use the tool to correlate changes and results. Helps build a foundation for performance profiling.

Anna (follow-up):
It’s a great learning tool. Especially helpful with the cause/effect graph—lets you understand what’s triggering expensive view updates.


My app is UIKit-based. Can I use SwiftUI scene types like menu bar extras?

Anna:
Yes. Use scene bridging. Lets you show SwiftUI scenes in UIKit/AppKit apps and apply scene-specific modifiers.

Taylor (follow-up):
Useful for integrating volumes and immersive spaces in VisionOS or customizing Assistive Access experiences.


Any bad practices to avoid when adding liquid glass to SwiftUI apps?

Taylor:
Avoid “glass on glass” (e.g., overlapping toolbars and scrolling content). Don’t use it everywhere—should convey meaning, not just be decorative. Avoid tinting for branding—color should signal purpose.

Nick:
Use GlassEffectContainer to manage how different glass views communicate. Helps performance and layering.

Curt:
Move branding color into content behind the glass, rather than tinting nav bars. That color scrolls out and glass falls back to default—better readability.


Any tips for improving LazyVStack performance with lots of items?

Nick:
Ensure your ForEach returns a consistent number of views. Wrap multiple items in a VStack so SwiftUI knows it’s a single row. Lazy stacks now benefit from prefetching (especially on macOS).

Taylor:
Reuse is an implementation detail. Focus on what’s expensive in your view body. Use the new performance instrument.


Low contrast in iOS 26 tab bar under dark content. What should we do?

Anna:
It's still in beta—file feedback! Avoid customizing standard components for now; we’ll adjust based on developer feedback.


Should I use SwiftUI to manage lifecycle if core views are still UIKit/AppKit?

Sommer:
Yes. Using SwiftUI lifecycle now will make future adoption of SwiftUI features easier.

Taylor:
It’s not binary—you can mix and match. Scene bridging supports bringing SwiftUI scenes into UIKit apps and vice versa.


Is MatchedTransitionSource a way to morph views from VStack to Sheet?

Anna:
Yes. It helps connect the interaction source to the destination (e.g., toolbar item → sheet). The zoom transition is interactable and creates a polished effect. Works with both toolbar items and regular views.


Should we use singletons or environment objects for view models?

Nick:
Avoid public static let shared. It’s hard to test and refactor. Use @EnvironmentObject to inject dependencies cleanly and testably.


Why does it feel like color is used less in the new design?

Taylor:
The liquid glass design emphasizes monochrome. Color now signals meaning (e.g., state, actions) rather than visual flair. Be intentional.

Curt:
Color is powerful but distracting if overused. Use glass components to signal interactivity instead.


Best way for a subview to send values back to parent, without binding?

Anna:
Use:

  • Container values (for container-style parents)

  • Preferences (values flow up)

  • Closures (for actions)
    Great example in the rich text editor demo—selection is passed up via a preference.


Are VisionOS widget animations available on iOS widgets?

Sommer:
Yes—since iOS 17. See the WWDC23 talk “Bring Widgets to Life” for animated/interactive widget techniques.


Can I add hyperlinks in the new rich text editor?

Sommer:
Yes. Use Foundation’s link attribute. Known issue in seed 1: gestures may not behave properly with links—we’re aware.


How do you implement custom tab bars in SwiftUI?

Anna:
Prefer system components when possible (e.g., for color, label customization). If custom, use GlassEffectGlassEffectContainer, and SafeAreaBar.


Can we show a chevron on a button (like a NavigationLink)?

Anna:
There’s no direct API, but:

  • Use environment key for indicatorVisibility
  • Combine with SF Symbols (chevron)
  • For polish, replicate NavigationLink’s selection state

Can we make a draggable glass droplet tab bar?

Taylor:
No API yet for draggable lift-up effect. Use GlassEffect APIs for other effects. File feedback with your use case—we love seeing creative ideas.


Can we unit test SwiftUI views like we did with UIKit?

Nick:
Focus on testing your models, not the UI directly. Avoid snapshot tests for navigation—test the model and view state instead. Makes CI faster and more robust.

Taylor/Anna:
Move logic out of views into models. Keep views small. Better architecture helps debugging and performance too.


What’s the best way to render thousands of thumbnails without jank?

Anna:
Minimize work on the main thread. Use Swift concurrency to offload decoding. Downscale large images to actual display size.

Nick:
Use the new performance instrument. Avoid expensive work in view bodies.

Curt:
Try the "disco ball" debug trick: randomize background colors in a grid. If your grid becomes rainbow while scrolling, you’re over-invalidating views.


Can DatePicker respect dynamic type?

Sommer:
Currently a known issue. Please file feedback.


Common SwiftUI anti-patterns to avoid?

Taylor:
Avoid conditional modifiers (if to apply/remove a modifier). Use “inert variants” like .opacity(condition ? 1 : 0)instead.

Nick:
Avoid conditionally inserting/removing NavigationStack. Keep stack static and switch views inside it instead.

Sommer:
Accessibility: Don’t forget about .accessibilityRepresentation { } when building custom controls.

Anna:
Avoid switching entire containers like NavigationStack in an if statement—it can reset scroll position and state.


When should I use @State@Observable@Bindable, etc.?

Nick:
Lean into @Observable. Architecture should remain testable and modular.

Taylor:
Fine-grained invalidation from @Observable is great. Don’t hold one big struct—prefer small pieces of data.

Curt:
Observable is getting stronger each year—worth investing in. Also check Swift Forums for future proposals.


Debugging SwiftUI: Any favorite techniques?

Anna:
Use self._printChanges() (spelled let _ = Self._printChanges()) to track why a view updates.

Sommer/Taylor:
Breakpoints, print debugging, and sound alerts help. You can add a sound to a breakpoint and continue without stopping.

Nick:
Random background colors in grids to see over-invalidation (the “disco ball” trick).

Curt:
See Swift concurrency sessions for performance tips. Especially Daniel’s session on SwiftUI annotations.


How do I use markdown but override font choices for bold/italic?

Sommer:
Use Foundation’s AttributedString(markdown:), then manually map .presentationIntent attributes to specific fonts. Then pass the resulting AttributedString to a SwiftUI Text.

(The following text was generated by Gemini 2.5 Flash to clean up auto-transcription errors. It is provided as an easier way to read the raw transcript.)
Also, if you have a bug or a feature request, please go to bugreporter.apple.com. Today, we want to focus on questions that will help the broader audience. So, please send us your questions using the Slido panel here in WebEx. Once our moderators approve the questions, they'll appear for everyone to upvote, so we can narrow in on the questions that are of most interest to all of you. So, let's jump in.
I'm going to claim moderator privilege and start with a couple of questions that I'm particularly interested in. So the first thing I would like to talk about to get the ball rolling is, I just want to ask each of you what your favorite new SwiftUI API is this year.
Sommer, why don't you kick us off?
All right, I'm going to have to go with our new rich text editor. It was a big labor of love for my team, and it was super fun, 'cause we got to work cross-functionally with Foundation, TextKit, CoreText, UIKit, AppKit, everybody.
Excellent. Nick, how about you?
Uh, for me, this is definitely a safe area bar, kind of an unsung hero. It's a coming together of a lot of concepts developers have known over the last few years, like scroll view insets, and safe area, and overlays, and it really marries those in a way that is really, really easy to use, and very satisfying.
Excellent. How about you, Anna?
Navigation Link, indicator visibility, or a way to both show and hide the chaperone on navigation links. And I just, it's a really popular developer request. It was super exciting to get to bring that to the platform this year, and also to get to back to play it.
Excellent. And, Taylor, how about you?
I'm going to cheat a little bit. I'm going to say all the new API we didn't introduce. I think one of the things I loved about a lot of the new features this year, across improving the performance of your existing lists or scroll views, or bringing the new design to all your existing components, I really love that we didn't introduce all a bunch of API that you have to adopt. It just comes to your apps for free.
Awesome. Um, so I want to turn to a couple of questions that we heard in the in-person labs, and, um, a segue to this, um, one of the favorite things that, to me, about SwiftUI this year isn't API at all, but it's the new instrument for SwiftUI, um, for profiling, um, your SwiftUI app. And, Nick, you, can you tell us a little bit about when developers should reach for that tool?
Yeah, um, so I think, with, like, with any kind of performance tool, if you're not a performance specialist and living in it day in day out, then it can be kind of daunting to reach for a performance tool. And so I really like to recommend that people reach for performance, like, maybe the best time to reach for these is when you know what's going on. So, you're building your app, you make one small change, and all of a sudden, you notice performance tanks. That's when you open the profiler, 'cause you can solve the problem and move along with your day, or you can open the profiler, and you already have a pretty good understanding of what's going on. And so, making that mental map between what you've done and what that looks like in the profile is a great way to learn and get a strong foundation for profiling performance. So when the day does come when you see something, especially pernicious, you're ready to go.
Excellent. Um, anyone have a follow up on that? Or when I had some color?
I mean, I love the point of sort of, like, using it to learn and going from there. I think one of the coolest things about the new tool is the cause and effect graph. Steven and Jed did an amazing job in their session, and so if you haven't watched that, you should check it out. They showed how you can kind of determine what's causing your expensive views to update. One little tip that they actually didn't have time to illustrate was, there are some cases where it's actually a SwiftUI live view that's taking, seemingly taking a long time, but the cause in a graph now lets you understand what your app may not be doing that's causing those SwiftUI views to update. And so it's like a really wonderful tool to really get insight into what's affecting your app.
That's awesome. Glad to hear all that. And also super excited about, um, just the performance improvements that the team made within SwiftUI itself this year. We talked about a little bit in the State of the Union on Monday, and certainly in what's new in SwiftUI, but I'm excited for people to try out some of that as well.
So the next question also came from the in-person labs, and I'll throw this one to you. A person asked, "My app is primarily UIKit-based, but I'm interested in adopting some newer SwiftUI scene types, like menu bar, extra, or other SwiftUI exclusive features. Has anything changed about how you can use those things in a SwiftUI app now?"
Yes, yeah. So this year, it is possible to use SwiftUI scenes from, like, your UIKit or AppKit life cycle app, with this thing that we call Scene Bridging. And so, it's a way to, like, show purely SwiftUI scenes from your UIKit or app code, and it's also cool because not only are you, like, showing the scenes, but you can also use, like, scene-specific modifiers that are in SwiftUI, but will go and affect that scene. So it's a really great way to think about introducing SwiftUI into your app.
Excellent. And I'd follow up on that to say that it also, if you have a UIKit app that you've brought to VisionOS, this is a great way to integrate volumes and immersive spaces into that app. The scene bridging works there as well. So it's super cool that way.
Yeah, or, like, if you're on iOS and you want to, like, customize your experience and assistive access, then that's, like, a really great way to use that scene type. Yeah, that's another super exciting thing that we've brought, um, the Assistive Access API to developers to use this year.
The next question is for Taylor, and it comes from Lior: "Can you share any bad practices that we should avoid when we're adding liquid glass to our SwiftUI apps?"
I mean, yeah, the liquid glass material is just so interesting and amazing. Like, I'm super excited about it, I imagine a lot of you all are super excited about it. But, you know, the design sessions I've shared, like, "Hey, how, when should you use it, when shouldn't you use it?" I mean, one of the key ones is avoiding, you know, glass overlapping glass. I think Caroline in one of the group labs yesterday talked about, like, the glass breaking or something. So this is a thing to avoid. You know, any place where you might apply it within scrolling content is typically a place to watch out for, because that could collide with the glass of the toolbars and navigation bars. You know, similarly, I think, a big emphasis was on color, right? It might be tempting to tint the glass for branding or other purposes, but really it should convey meaning to people, right? It's drawing attention. It is a very cool visual effect, but it should be reserved for those attention-requiring cases.
I wanted to jump in. One of the places we ran into with a lot of adopters this year is definitely remember to put your glass in appropriate groups, and we talk about this in some of the WWDC sessions. I forget the exact name of the group API, maybe somebody knows, but that helps the glass properly communicate with other glass and kind of know that it's there without having to scan the whole screen and look all over the place.
Right. Then it's the `GlassEffectContainer`, and totally true. Go. Um, and the other thing I'd like to call out there that, um, folks talked about a lot when I was chatting at our, uh, in-person event here on Tuesday. A lot of apps will have historically tinted their navigation bars in order to convey branding, and that's going to conflict with the liquid glass in the navigation bar. And so what we did in the news app, and what we'd encourage your teams to investigate, is move that color into the content, into the scroll view. So when someone enters that view, that branding color is there, it's behind the liquid glass, the liquid glass highlights it, emphasizes it. But then as someone scrolls, that moves out of the way, and the controls fall back to their basic monochrome style, which we think people will find easier to read. So that's something to talk about within your teams, talk about with design, and figure out how to deal with that branding color without actually tinting the bars or the backgrounds of sheets.
Mm-hmm. It's one of the coolest parts of the adaptive glasses, how it just, like, lets that color come through when it's right at the top. It's super neat to just see it pop.
So, next question, I'm going to throw Nick's way, and this is a follow-up on the performance thing. So, "Thanks for improving list performance. Questions from Art: What about lazy V stacks and scroll views? Does it, uh, reuse cells? Are there any best practices around improving performance when using LazyVStack with a large number of items?"
Uh, definitely, yeah. So people have talked to some of the improvements made around prefetching on macOS this year, and we did see some serious improvements internally. One tip that is especially good to look out for when you have a large number of items is that your `ForEach` is returning a static number of views. And so that kind of means that you aren't returning multiple views from within that, and that can be solved by as simple as wrapping your multiple views in a VStack. And so that tells SwiftUI, "Oh, this is just a single row," and we can make optimizations based off that. Um, I wonder if anyone else can kind of talk to that distinction or any other tips, uh, around master scroll performance. Like, across the board, we really did improve scroll performance, and idle prefetching is, like, one big highlight, but even across all the other performs, there was, like, improvements under the hood to make this better without you needing to do anything. The question asked about reuse, and one thing is that's kind of powerful about SwiftUI is, because it's so declarative, reuse is basically an implementation detail. We really try to optimize things and use reuse, or don't reuse, reuse under the hood to do the best result for your apps. So, I would really look at things like the performance instrument to figure out just what's expensive about your views and what your app could do to make that better.
Excellent. And again, I'd also call out the new instrument, which I'm so excited about. If you do think you're having some performance issues in scrolling, if you're seeing hitches, try it with the instruments, see if that helps you narrow it in on what the problem might be.
So the next question, I'm going to throw your way, Anna. This is from Amir: "So, implementing the new iOS 26 tab bar, it seems to be very low contrast when there's darker content underneath the tab bar. Is there anything we should be doing to increase the contrast in our toolbars or tab bars?"
Thank you for the question. Thank you for noticing that and thinking about that. I would say, honestly, the new design is still in beta. That would be a really awesome feedback to file. I would probably recommend, especially, like, it's in beta right now, I would recommend against trying to modify, like, the standard system components, but I would, like, file a feedback so that we're able to take that into account, like, across the system for all apps.
Yeah, and this is a great place to call out that, like, all of our apps on the platform have been adopting liquid glass, and so we're tuning the experience based on those. But this week is the opportunity to get all of your apps onto the new, onto the new design, and to see how they perform. And this much larger pool of apps testing the system is going to be a great way for us to make it better for you and for all of our shared customers. And so that feedback early this year is super important, and we're really looking forward to that.
Yeah, and I think, especially when that feedback is around things like contrast or other accessibility issues, like, there's just such a wide matrix of different things that can happen in your apps and ours, and getting that to us is so, so valuable right now.
Sommer, let's stick with you for the next question. This one comes in from Nuno. Um, yes, or they ask, excuse me, um, "If I'm starting a new multiplatform app, so I'm going to deploy to iOS, iPadOS, macOS, for example, but I know that it's heavily going to depend on UIKit or AppKit views for some of the core structures. So, using `NSSplitView`, or, you know, a `UICollectionView`, et cetera, should I still use SwiftUI to manage the app lifecycle? What do I think about in making that choice?"
That's a really good question. And I would generally say yes, it's still going to be a great foundation for you. And by using SwiftUI, kind of as you're starting point to handle the lifecycle, it's going to just make it easier when maybe you want to add some SwiftUI components in the future, or perhaps we add new components and you're like, "Oh, I really want those," then you're going to be setting yourself up for success to kind of quickly iterate, because that lifecycle of management's all already there. But I imagine, actually, Taylor might have some more thoughts on this as well.
I mean, everything that Sommer said was totally true, and, like, this interoperability, um, has been at the core of SwiftUI from the very beginning. You know, we had a lot of the core APIs to go back and forth between SwiftUI, UIKit, and AppKit at the beginning, and every year, we add more, right? And I talked about the Scene Bridging, where, if you build part of your app and you realize you need to actually utilize, uh, you might interactive lifecycle, you can bring all the existing SwiftUI scenes you've already built up into that app, or, or vice versa. So, it's really a core part of it that you should think of it not as a binary choice, but as a mixing of whatever you need.
Great advice, thanks. And I'm going to throw this next one to you. This question comes from David. David says, "I'd love to know more about the `matchTransitionSource` API that you've added. Is it a native way to have elements move from a VStack to a sheet? And what's the use case for it?"
Lee, um, so, that would be, it's kind of, yeah, it's a good way to kind of, like, connect those different views, like, kind of, like, this year, you know, when you present, um, like, popovers or other presentations, like, out of, like, all bar items, it's kind of a way to, like, connect, like, what, like, your interaction to the thing that then it's showing. Like, I think for, like, a VStack to a sheet, yeah, it might be that, like, they're connected, or, for some reason, like, you're not, like, I'm thinking about it, like, maybe, like, someone's performing an action, and it's, like, making it go larger, so it's, like, zooming in and out. The other thing, I think, is super cool about, like, that transition, particularly, like, the zoom one, is it's, like, fully interactable when people can, like, swipe it. It just creates a really, really nice experience. And so we have support for that this year and toolbar items, and since last year, we've also supported that with just, like, normal views like your VStack.
Excellent. Thank you. Um, Nick, the next one, I'm going to throw your direction. Um, so, this comes from David: "Is it `instance singleton`, or `environment object`, per view models? What a great question. Recommendation."
Yeah, so who hasn't written `public static let shared` at least 10 times in the last year? But I see this a lot in client code. I see this a ton, and it, everyone's so familiar with it from Kit days, but at the same time, in SwiftUI, it really kind of makes, right off the bat, it makes your code more difficult to test. And then on top of that, the `environment object` is really trying to take care of that for you, so that the problem that's shared with solving in the past was getting at this singleton from anywhere. But with `environment object` that's not really a problem anymore. You put this object at the root of your hierarchy or wherever you need it, and then people use the environment APIs to access it. And so, `shared` isn't actively harmful, but it does make things more difficult, and it makes refactorings more difficult, and, uh, hopefully, that explanation kind of made sense, and you go, "Remove one `public static let shared` in front of your, uh, from your code base."
I think previews are another great example where, like, using `environment object` lets you kind of inject different contexts for different previews, um, to school.
Um, Taylor, let's stick with you, uh, for the next question. Um, and this question comes to us from Andrew. Um, Andrew asks, um, "I've noticed with the new design language that SwiftUI views appear to not use color as much. For example, color modifiers for list view items like carets. Is this intended? Can developers introduce color back into elements, if desired, like moving back to something like the iOS or iPadOS 18 style?"
Yeah, no, that's a great question, and I'd really honestly recommend watching some of the new design sessions this year that go into a lot of detail about sort of the design motivation, how to think about color. Um, I think it is true that in general, you know, the liquid glass takes advantage of what we call monochrome, uh, controls on top, and so I would avoid sort of, quote, arbitrary tinting of things, but tinting is super important to communicate things to the users of your app, you know, to draw attention to key actions, or to indicate a piece of state. And so the color is actually playing an even, even bigger role, because it's indicating those things, as opposed to just visual visual flair. So I think it's kind of a cool opportunity to look at how exactly you use color and really make the most of it.
Yeah, one thing folks will find, as, you know, they use the betas of the new operating systems, is that with liquid glass design, and the new design system, color really draws the eye, maybe more than it did before. And where before, we might have used color to indicate, "Here's an action." We have glass around buttons and controls now, and that indicates that this is an action. And so, if you introduce too much color with these bright, you know, beautiful glass elements, it's hard for people to concentrate, because it draws their eye too much. And so, this means that color is really powerful when you do want to draw someone into a particular area of your app or into a particular action, but you really have to be careful not to overwhelm people with too much color.
And I'm going to throw the next question your direction. This comes from Michelle. "What's the best way, in SwiftUI, for a view to communicate values back to its parent that cannot be overridden by the parent? `Binding` is not really suitable, because that allows the subview to write back to the superview. But what's the right way to think about doing that?"
Yeah, that's a really good question. I agree that `Binding` does not sound like a very good tool for doing that. Um, but SwiftUI does have tools that enable you to, I think it partially depends on like what that parent actually is. So if that parent is a container, I would recommend taking a look at `ContainerValues`, which are these values that are able to be read by a container. And there's a really great WWDC talk last year from Matt on our team about that. And then if you are kind of just communicating it up, honestly, kind of, you want to go up instead of down like you might in the environment, I would take a look at `Preferences`. So with `Preferences`, they flow up, and then you'll implement something that kind of, if there are multiple preferences, deciding what you should do to go and combine those. So those won't get modified unless you're doing, like, that reduce, and then also consider, like, using closures, that's particularly good, like, if you need to perform an action, or also if, like, you may need to interact with some of the Kit views like UIKit or AppKit.
Awesome, I'm going to take this opportunity to shout out, um, our talk on rich text and, um, `AttributedString`. There's an amazing sample code project with that on using the new rich text editor. But one of the things that Max and Jeremy did in that is they used a preference that is passing the current selection up the view hierarchy, and then they have an inspector. And so you can highlight the name of an ingredient in a recipe, and in the sidebar, it shows up as something you can add to your ingredient list or your shopping list. It's just a great, real-world code example of using preferences to communicate information. So I'd really encourage people to check that out, and check out that session video also, because it has a lot of fabulous Easter eggs that I think you'll enjoy.
Oh, Gundland. So, Sommer, I want to throw the next question, next couple of questions to you. So strap in. Um, this question comes from Evelyn: "Thanks for the question, Evelyn. I saw that animations are available in widgets for VisionOS. Are they also available for widgets on iOS?"
Yeah, so the same animations, uh, things that are available on widgets for, uh, for VisionOS have been supported on iOS. I think since 17, since iOS 17. So like tweaking animations for entry transitions and things like that. But if you want more information, there's a talk from WWDC 23, um, which is "Bring Widgets to Life," which is an awesome talk. And that's going to talk all about animated and interactive widgets for apps or for games or anything like that. So definitely recommend taking a look at that talk.
Excellent, thanks. Continuing with you, Sommer, this question comes from Fred: "Is it possible to add hyperlinks to the text inside a rich text editor?"
Ooh, good question. I was just in this code, so this is very fresh in my mind. Yes, yes, you want to use the Foundation's `LinkAttribute`, so that's going to be like `AttributeScopes.FoundationAttributes.LinkAttribute`. And that's what you'll use to do that. But note, in seed one, there is a known issue that we are aware of, where the link gestures aren't behaving correctly. So that might be why you're asking this question. That is something we're aware of.
Excellent, thanks. Um, and, uh... I appreciate that you've been in that code lately, Sommer. It's a good time. It's very exciting when a manager gets to go into code. Like, "Wow, big day."
That is the most exciting thing, yeah. Thank you, Jay. Uh.
So, Anna, I'm going to throw the next question your way. This is from Bastille: "What's the best way to implement custom tab bars in SwiftUI?"
Yeah, I mean, you have a few different options. I will just, like, preface this, and I'm going to sound like a broken record, but I would recommend taking a look at if you're able to use the standard system controls for what you're trying to build. So, like, we offer different APIs that allow you to customize things like the color or the label, or, like, there's a really cool one this year for, like, you know, showing, like, a separate search tab, kind of seeing if those will work for you, because then you get kind of the right appearance across, like, all of the operating systems prior to the new design, with the new design. If you are looking to do something that is, like, way more custom, and that's still what you're looking to do, I would take a look at, like, the new glass APIs, like `GlassEffectContainer`. I think that's the one that Nick was alluding to previously. And then, like, `GlassEffect`, and also the `SafeAreaBar` API, to be able to, like, build things that are a little bit more like what we have on the system.
Excellent. Also, one other thing, file a feedback. If there's, like, some little thing where it's, like, "If only you had this, I would be able to use it." Like, that's also really helpful feedback for us to know.
Excellent. I appreciate that. Um, and I'm going to stick with you for the next question. Excuse me. This comes from Zack. Um, and I think we mentioned this up top, but, um, we mentioned a little bit about this up top, but, um, the question is, specifically, "Is there API to show the navigational link chevron when there isn't a navigation link, but it's a regular button?"
Yeah, so there isn't an API right now. We would definitely be curious to hear more about your use case and, like, why, like, a button versus a navigation link for that. The other thing I will say is you can, um, read the indicator visibility out of the environment, and that is one thing that may be a helpful tool if you want to create, like, button-like navigation links, just to be able to kind of align with the system defaults there.
Yeah, and, um, I also point out that, um, the, uh, trailing chevron, um, SF Symbol is what navigation links are styled as. And so there is an SF Symbol for that, so it's to combine that in an image with that environment key that Anna mentioned. That gives you the pieces to build this. So, while there's not direct API, it's not too many steps to get there. The other thing I will say, this is, like, more of a polish detail, but if you have, like, your navigation link in some selectable container, also do consider, like, selection when you were doing that. Like, say, you have a button, and you have, like, a selectable list, you may want to make sure that, like, your selection state is aligned, 'cause, like, when you select a navigation link in SwiftUI, that does, like, show as selected when then it pushes. And it has that very subtle effect that shows us selected as you're coming back from whence you came, which is, like, you can see in Mail. That is, uh, and that is a challenging thing to get right, as all of my colleagues who've worked on navigation can attest.
Um, the next question I have to ask, just because of the developer's name, this question, this is really for anyone on the panel, but maybe we'll start with you, Taylor. This comes to us from Fruit Coder: "Can you create custom components, like the tab bar, with a fluidly draggable glass droplet over them?"
I see, yeah. So, probably echoing, you know, what Anna said about, you know, using standard components in UIKit and, you know, moving to building custom components when you need to. So there is, obviously, the new `GlassEffect` API, which lets you build custom liquid glass components. I think you maybe are referring to this little lift up effect that appears when you change selection. There's currently not API for that, but do file feedbacks if you feel like you're having use cases where you want additional API for creating the effects you want in your custom controls. I think we always love to hear that of what people are trying to do, and trying to make.
Yeah, and I'm going to echo that. Sometimes we sound like a broken record asking for feedback on things. But this comes back to the thing I mentioned earlier about how we see how developers within Apple are using the APIs, and that informs the design of the API, but we can't anticipate everything. Like, our developer community is endlessly creative. And so getting feedback that has screenshots or description of the use case can really help us understand the full scope of all of our developer community's needs, so that the team can design API that is generally useful. Like, the team works very hard to build API that is simple and flexible and composable. And sometimes you just need a lot of input in order to understand what the use cases are that that API has to cover. So that feedback is just invaluable to us, and we really appreciate it when folks can take the time to feed that file that.
And I do love the name, too. Yes. Um, so the, uh, the next question, um, comes to us from Jeff, and Nick, I'm going to, I'm going to let you start on this one, but maybe we can throw it around the horn. "Do you have any tips on how we can unit test our SwiftUI views, like the way we did with our UIKit views? Is there a way we can do that without the need of a third-party library?"
Yeah. Uh. First of all, Jeff, thank you for this question. I think about this a lot. Bro, I think about this probably three times a day, every day.
He really does. He really does.
It's so important, and so important, and it's a tricky answer, and I can't give a prescriptive one that will kind of cover everybody's cases. So, I'll start off by saying that, if you think about where the majority of your bugs lie, in my experience, that's most often, or many times, in the business logic. And so, if you can catch those bugs in your business logic, there's no need to be directly testing that against your SwiftUI views, and that probably, generally, that even makes the test a little too comprehensive. Um, and testing not exactly what you're going for. And so that's one example, and I can give a concrete example of testing that. So a lot of people like to test login flows in their app, and that's a really important flow to test. And when you're working on that, you can kind of typically have your navigation stack, and you push from your username password field into your next view, and you might be tempted to test that with, like, a snapshot test, where you check that that pushes. Um, but I would, I would challenge kind of that assumption and say maybe a better, or, a more testable architecture to take would be to put that data in a model, and test that when you populate, populate the username and password field of your model, and submit that, that now your navigation path contains, you know, home screen. And that is a really quick test, right? That test is executing in milliseconds, not seconds, in your CI system. So, that's one example. I wonder if any other panelists kind of have other favorite, favorite things to think about.
Yeah, I think I would also say, like, there are some modifiers in SwiftUI where, like, you are performing in, like, it's performing an action as a result, and kind of going off of what Nick was talking about previously, thinking about, "Hey, how can you move that logic out of your views and into your models?" So maybe it's, like, I'm trying to think of one, but, like, I don't know, on change of a particular value, you want to do something. Like, you may want to make it so that that's not, like, performing actions directly, but it's calling into a model or something else, so that then you're able to, like, unit test that separately, and not have to be, you know, in a SwiftUI view to do that.
Yeah, beyond unit testing, like, I find that people who take, like, a hard look at what their relationship is with their model versus their views, and really try to keep their views, you know, quite as small as possible, often end up with just better apps as well, like, beyond the unit testing, right? They have kind of a more understandable view hierarchy. They have kind of fewer bugs because they're able to do this unit testing, or they're just able to reconcile it a lot better. So I think it's a great question about unit testing, but a lot of these ideas just help your app at the end of the day, which is a really cool thing.
Yeah, I think we try to design, and I think we do design our APIs in a way that's architecture agnostic, but I think I'm not saying anything too controversial. Oh, here, when I say, whatever architecture you pick, have a testable architecture, and, uh, that what Taylor just said is great. And it's tricky. It is tricky to get that right, but it's a great thought exercise, and it pays big dividends.
Excellent, thanks. So the next question I want to address is coming to us from Sam, and Sam says, "We're building an ultra high-performance photo library grid view. Can't wait to see it, Sam. But Sam's question is, what's the recommended way to display thousands of thumbnails in a `LazyVGrid` without dropping frames or showing empty cells as the asset thumbnails load in? What are some things we can do to improve that?"
Yeah, I mean, I think... Go ahead, Anna.
I think the first thing I would say is, consider what work you need to be doing on the main thread versus what you can do, like, off of the main thread. There are some really, really great Swift concurrency talks this year that kind of talk about, in particular, I think, Kurt, you probably know the full name, but "Embracing Swift Concurrency" kind of takes you through that journey of, like, you start with everything on the main thread, and then you start, like, moving things off as you find, you know, your app needs it. The SwiftUI performance instrument can be a great way to also figure out, like, are there issues with scrolling or other things that are happening because you're doing, um, a lot of work on there. The other thing I would say is, like, for high resolution images, consider scaling them down to the display size. Just do the amount of work that the display needs, not more than that. But I'm curious if anyone else has thoughts on that.
I'm never going to resist another chance to plug the instrument, so I'm going to jump in and say, the new instrument, I think, is great, 'cause the thing you want to watch out for is your view initializers or your view bodies being too expensive, right? So any, like, image decoding work you're doing there really should be moved off, like Anna said, and the instrument can help reveal when maybe you're doing that when you didn't even realize. So, one plug for the instrument, curious if anybody else has other elaboration.
One really... I'll... Oh, go ahead, please.
Uh, I just, I remember this demo from two years ago, when we were doing performance lists, a performance work, um, on list, and Hautian, who is a fantastic member, who just does amazing demos, did this demo where, uh, he visualized how fast cells were invalidating on the list, and you can typically do that with color. And so, uh, take your photos, give them a small inset, and give them a background, uh, and make that background color dot random. And so flick the scroll, you know, flick the list, and if you see an absolute disco ball, you're in trouble, right? Because all your photos are invalidating for reasons you don't know, and they shouldn't be. And so that's a great debugging technique. It's just that random background color to see what you're invalidating, and go from there.
It's very appropriate that you mention the disco ball, Nick, I think. Is it right? Excuse me, Anna, I, uh, I appreciate the call out to, uh, to Doug's session, uh, on embracing, um, Swift concurrency. We also have a couple of follow-up sessions on that. Um, Sema did a session. It's a Codalong, "Elevate an App with Swift Concurrency," which looks like at specific techniques for using concurrency to improve performance, and it's got this great corgi in it, so you should watch. And then Daniel also did a fabulous concurrency session. This explicitly about the concurrency annotations in the SwiftUI framework, and how to understand what those annotations tell you about the behavior of SwiftUI. And it's a really, to me, um, a fascinating dive into the details of the framework, and how to think about this when you're writing your code. Um, so I encourage folks to check that out as well.
So Nick, um, here's a question for you from Zach. "Can you provide some tips for making your SwiftUI views more accessible with the new pointer APIs?"
Yeah, uh, so the, actually the new pointer APIs this year, uh, are primarily UIKit and AppKit APIs. And so, what we've seen is, with SwiftUI, because of how kind of easy it is to declare new custom controls that sometimes don't have, like, the right accessibilities built in, uh, it's often great to take the time to go in and kind of make sure that your custom controls are just like a proper, uh, control for accessibility, and it's especially great on this, um, with our new accessibility tools. So, for example, if you, like, have your own custom button, you can, like, mark it as, you know, a button, and you can also add, like, the correct actions associated with it. And so that's something that is, like, especially helpful. And we do have an accessibility session from, I think, 2022 that talks about building custom controls and making them accessible. I would highly recommend taking a look at that if you're building any custom controls.
I also jump in on that and say, one of the things we've been, you know, as a team, we've been really enjoying this year is that so many of the changes we've made around the system design of liquid glass have come along with improved accessibility. And a great example of this is actually the new inline menu. You know, we had a new API for menus this year that allows you to specify that it should be in line, but that also lets us improve the experience when you, for instance, use the menu with Voice Control, or with a pointer that's pointing to the menu, so you can interact with it in a much more fluid and natural way than before. So, it's really exciting that so much of the design work, so much of the visual design work, has gone hand in hand with our accessibility work this year.
Excellent. So, Anna, I'm going to throw this next question to you. This is from Tom, and Tom asks, "Is it possible to show the new design system to users if they are not running iOS 26?"
That's a really great question, and thank you for asking that. No, the new design system is only available on iOS 26 and later. And so, um, we always want to encourage you to build the best experience for your users. So if you're able to deploy on iOS 26, then you should do that, because you get it for free, but if you're not able to, then we would recommend deploying on iOS 25, or later, or earlier, and, um, you will just get the iOS 25 appearance by default then.
Excellent, thanks. Um, Taylor, I'm going to throw the next question to you. This is a philosophical question from Mark: "How do you think about the future of declarative versus imperative UI frameworks, as, for example, UIKit continues to grow, and what are the, uh, what are the use cases for each?"
I mean, that's a great question, and I'd really look at it like, I mean, the proof is in the pudding, right? Like, the reason why you're all here and I'm here is because we're super excited about SwiftUI, and because it has allowed you all to express your apps and what you want to build in them in an even more straightforward and, you know, sort of less boilerplate kind of way. And so I think that really speaks for itself, and I think we're seeing, you know, year over year, just more and more excitement about SwiftUI, and that's why we're really focused on bringing to all the platforms and improving the experience with it. So, I mean, I think that's the story, but I'd also echo what I said earlier, which is, it's not a binary choice, right? We have worked for the last five years, and we'll continue to work really hard, to make sure that these frameworks interoperate really seamlessly, because there's just so much code and so many amazing apps that have been built on top of UIKit, and for example, this year, we just finished this long journey to bring text from being totally imperative to totally declarative, and you saw the new rich text editor, which I think is a great example of that journey. And so that's the kind of thing you're going to continue to see from us.
Yeah, I think for me, it's that, like, the, um, declarative design of SwiftUI is actually just making it possible to build things that were previously very difficult or impossible to do in the imperative frameworks. And so you're seeing those come through, you know, on the platform in ways that are, like, super delightful to users because, you know, the system is designed to provide those experiences. But that's only possible because we can make assumptions in the declarative design. And so, that's something I'm very excited about.
So, one more question about text, this is from Nuno, and I'm going to throw this to you, Sommer: "Is there a good way to use a rich text editor if you're using a single font throughout your app?"
Yes, you can totally do this. You're going to, like, use `TextView` in the editor, and you're going to use the `.font` modifier, and that will make it so that your `TextView` has the correct font. It's also super nice because it'll go and pick up the correct size for the `TextView` based on, like, whatever, uh, text size, Dynamic Type size, that you have there.
Excellent. Thanks. Um, so I want to just turn to some of the general questions. Um, this is probably one of the most upvoted ones across a bunch of the labs, and I'll throw this to you, Nick, and then we'll all just kind of chime in on it. "If you, uh, if you could give only one piece of advice to SwiftUI developers, what would it be?"
Yeah, I mean, if I'm thinking about giving the one piece of advice, then I think I would say, it's kind of to lean into the framework, and I know that sounds, uh, kind of a little bit high level, but I, I see a lot of people try to take the patterns that they've learned from previous imperative frameworks like UIKit and AppKit, and try to apply those directly to SwiftUI, and it doesn't always, uh, give you the best result for yourself. And so I think, like, lean into the environment APIs, and the, uh, data flow APIs, and don't try to, like, build all these layers of abstraction, like, we've thought a lot about this, and we've built, built this in a way that should be really easy and straightforward to pick up. And so that's, like, my biggest piece of advice, is just try to trust that the framework is built for you, and try to lean into it.
Yeah, I mean, I would add, as well, like, if I had to give one piece of advice, it would be, sort of, like, don't be afraid to try things. Like, sometimes, I think people look at Swift UI and it seems, you know, complicated, but it's, like, it's just such a delightful framework to kind of just like, you know, iterate on something, and then, you know, make a new thing, and kind of build something and get it on screen really quickly. And so, like, don't be afraid to sort of, like, you know, just mess around, and sort of try different things.
Yeah, I would sort of piggyback off of that and say, like, play with your previews. Like, they're so powerful, and they're always getting better, and you can sort of, like, change the device, change the orientation, change the Dynamic Type size. And, like, you're able to really, like, quickly iterate and understand what your SwiftUI views look like in all these various configurations.
Yeah, and I would add, um, take the time to really understand the data flow, because it's such a fundamental concept to SwiftUI, and it's also, um, it's so helpful for getting a, a good understanding of what the framework is really doing, and what its intentions are. So if you haven't watched the "Data Essentials in SwiftUI" talk from a couple of years ago, I'd really encourage you to do that. It's an older talk, but it's still, like, super relevant, and really, really helpful for, uh, for setting yourself up for success there.
Yeah, I would also add that, um, to like, keep your views small. I think people often get into a rut of, like, trying to put everything into one SwiftUI view, and that, like, can really cause problems. So I would like, keep your views small. Um, and the other thing, I know we've talked about it a lot, but I'm gonna say it one more time, use that new SwiftUI instrument, like, it's just so powerful for helping you figure out what's going on in your app.
Excellent. So, I have one more question, and I'll open it to the panel. What's been your favorite part of this year's WWDC, or your favorite memory from a past WWDC? Taylor, let's start with you.
I mean, I think my favorite part of WWDC is probably just, you know, interacting with all of you, like, getting to see everybody here in person, and getting to see all of you in Slido. Like, this is why we're all here, right? We're building frameworks and apps, and we want to hear how they're working, and we want to help you build great apps. So, I think that's my favorite.
Yeah, I, I really enjoyed being in person this year and just like, seeing all of the energy and excitement from everybody around. And then also just getting to watch all of the sessions, there's just so much good content and just so much good work that my colleagues had built, and build little apps with it, and it was just super enjoyable.
Nick, you're next.
I hosted SwiftUI's fourth birthday party. My favorite part about that session was making it fun. Fourth Perth, yeah, yeah. Just making it fun, and just kind of, you want to make it very approachable, and so, if you watch that session, there's a ton of stuff in the background. There's a fully baked cake, custom frosted with SwiftUI, and I believe in it, there's, like, a whole host of people who help put on the, you know, there's camera crew and audio crew, and directors, and I offered everybody a slice of this cake. And no one ate the cake, and so I had to take the cake home. And, like, eat all cake myself, so, um, I just like making it fun.
That's wonderful. Taylor, how about you?
Yeah, so, yeah, Matt and I were the first to share what's new in SwiftUI in the first years. And one of the most challenging but fun things to me, and that's true for, I think, every year, is there's so much that's new, right? And we can't talk about everything that's new. So it's really challenging, but fun, to figure out what are the things that we think people are going to be the most excited about, and how do we form that into this story that makes so much sense? And I think every year, it's successful and every year, I love seeing how everybody makes it their own. So it's so exciting for me to see, every other year, getting better and better. So it's really great.
Also, if you have a bug or a feature request, please go to bugreporter.apple.com. Today we want to focus on questions that will help the broader audience. So, please send us your questions using the Slido panel here in WebEx. Once our moderators approve the questions, they'll appear for everyone to up vote, so we can narrow in on the questions that are of most interest to all of you. So let's jump in. I'm going to claim moderator privilege and start with a couple of questions that I'm particularly interested in. So the first thing I would like to talk about to get the ball rolling is, I just want to ask each of you what your favorite new Swift UI API is this year. Summer, why don't you kick us off? All right, I'm gonna have to go with our new rich text editor. was a big labor of love for my team, and it was super fun, 'cause we got to work cross functionally with foundation, text kit, cortex, UAKit, app kit, everybody. Excellent. Nick, how about you? Uh, for me, this is definitely a safe area bar, kind of an unsung hero. It's a coming together of a lot of concepts, developers have known over the last few years, like scroll view insets, and safe area, and overlays, and it really marries those in a way that is really, really easy to use, and very satisfying. Excellent. How about you, Anna? Navigation link, indicator visibility, or a way to both show and hide the chaperone on navigation links, And I just, it's a really popular developer request. It was super exciting to get to bring that to the platform this year, and also to get to back to play it. Excellent. And, Taylor, how about you? I'm gonna cheat a little bit. I'm gonna say all the new API. We didn't introduce. I think one of the things I loved about a lot of the new features this year, across improving the performance of your existing lists or scroll views, or bringing the new design to all your existing components, I really love, that we didn't introduce all a bunch of API that you have to adopt. It just comes to your apps for free. Awesome. Um, so I want to turn to a couple of questions that we heard in the in person labs, and, um, a segue to this, um, one of the favorite things that, to me, about Swift UI this year isn't API at all, but it's the new instrument for Swift UI, um, for profiling, um, your Switch UI app. And, Nick, you, can you tell us a little bit about when developers should reach for that tool? Yeah, um, so I think, with, like, with any kind of performance tool, if you're not a performance specialist, and living in it day in day out, then it can be kind of daunting to reach for a performance tool, and so I really like to recommend that people reach for performance, like, maybe the best time to reach for these is when you know what's going on. So, you're building your app, you make one small change, and all of a sudden, you notice performance tanks. That's when you open the profiler, 'cause you can solve the problem and move along with your day, or you can open the profiler, and you already have a pretty good understanding of what's going on, and so, making that mental map between what you've done, and what that looks like in the profile, is a great way to learn and get a strong foundation for profiling performance. So when the day does come, when you see something, especially pernicious, you're ready to go. Excellent. Um, anyone have a follow up on that? Or when I had some color? I mean, I love the point of sort of, like, using it to learn and going from there. I think one of the coolest things about the new tool is to cause an effect graph. Steven and Jed did an amazing job in their session, and so if you haven't watched that, you should check it out. They showed how you can kind of determine what's causing your expensive views to update. One little tip that they actually didn't have time to illustrate was, there are some cases where it's actually a swifty live view that's taking, seemingly taking a long time, but the cause in a graph, now, lets you understand what your app may not be doing, that's causing those swift dive used to update. And so it's like a really wonderful tool to really get insight into what's affecting Europe. That's awesome. glad to hear all that. And also super excited about, um, just the performance improvements that the team made within Swift UI itself this year. We talked about a little bit in the state of the Union, on Monday, and certainly in what's new, in Swift UI, but I'm excited for people to try out some of that as well. So the next question also came from the in person labs, and I'll throw this one to you. person asked, My app is primarily UI kit based, but I'm interested in adopting some newer Swift UI scene types, like menu bar, extra, or other Swiss UI exclusive features. Has anything changed about how you can use those things in a swift UI app now? Yes, yeah. So this year, it is possible to use swift UI scenes from, like, your UI kit or app kit life cycle app, with this thing that we call scene bridging. And so, it's a way to, like, show purely swift UI scenes from your UI kit or app code, and it's also cool because not only are you, like, showing the scenes, but you can also use, like, scene specific modifiers that are in Swift UI, but we'll go and affect that scene. So it's a really great way to think about introducing Swift UI into Europe. Excellent. And I'd follow up on that to say that it also, if you have a UI kit app that you've brought to Vision OS, this is a great way to integrate volumes and immersive spaces into that app. The scene bridging works there as well. So it's super cool that way. Yeah, or, like, if you're on iOS and you want to, like, customize your experience and assistive access, then that's, like, a really great way to use that scene type. Yeah, that's another super exciting thing that we've brought, um, the Assistive Access API to developers to use this year. The next question is, is for Taylor, and it comes from Lior, can you share any bad practices that we should avoid when we're adding liquid glass to our Swift UI apps? I mean, yeah, the liquid glass material is just so interesting and amazing. Like, I'm super excited about it, imagine a lot of, you all are super excited about it. But, you know, the design sessions I've shared, like, Hey, how, when should you use it, when shouldn't you use it? I mean, one of the key ones is avoiding, you know, glass overlapping glass. I think Caroline and one of the group labs yesterday talked about, like, the glass breaking or something. So this is a thing to avoid, you know, any place where you might apply it within scrolling content is typically a place to watch out for, because that could collide with the glass of the tool bars and NAV bars. You know, similarly, I think, a big emphasis was on color, right? It might be tempting to tint the glass for branding or other purposes, but really it should convey meaning to people, right? It's drawing attention. It is a very cool visual effect, but it should be reserved for those attention requiring cases. I wanted to jump in one of the places we ran into with a lot of adopters this year is definitely remember to put your glass in appropriate groups, and we talk about this in some of the WWDC sessions. that I forget the exact name of the group API, maybe somebody knows, but that helps the glass properly communicate with other glass and kind of know that it's there without having to scan the whole screen and look all over the place. Right. Then it's the glass effect container, and totally true. Go. Um, and the other thing I'd like to call out there that, um, folks talked about a lot when I was chatting at our, uh, in person event here on Tuesday. A lot of apps will have historically tinted their navigation bars in order to convey branding, and that's gonna conflict with the liquid glass in the navigation bar. And so what we did in the news app, and what we'd encourage your teams to investigate, is move that color into the content, into the scroll view. So when someone enters that view, that branding color is there, it's behind the liquid glass, the liquid glass highlights it, emphasizes it. But then as someone scrolls, that moves out of the way, and the controls fall back to their basic monochrome style, which we think people will find easier to read. So that's something to talk about within your teams, talk about with design, and figure out how to deal with that branding color without actually tinting the bars or the backgrounds of sheets. Mm hmm. It's one of the coolest parts of the adaptive glasses, how it just, like, lets that color come through when it's right at the top. It's super neat to just see it pop. So, next question, I'm gonna throw Nick's way, and this is a follow up on the performance thing, So, thanks for improving list performance as she is. Questions from art. What about lazy V stacks and scroll views? Does it, uh, reuse cells, are there, are there any best practices around improving performance when using LazyBe Stack with a large number of items? Uh, definitely, yeah. So people have talked to some of the improvements made around prefetching on macOS this year, and we did see some serious improvements internally. One tip that is especially good to look out for when you have a large number of items, is that your 4 each is returning a static number of views, and so that kind of means that you aren't returning multiple views from within that, and that can be solved by as simple as wrapping your multiple views in a V stack, and so that tells 52I, oh, this is just a single row, and we can make optimizations based off that. Um, I wonder if anyone else can kind of talk to that distinction or any other tips, uh, around Master Scroll performance. Like, across the board, we really did improve scroll performance and idle prefetching is, like, one big highlight, but even across all the other performs, there was, like, improvements under the hood to make this better without you needing to do anything. The question asked about reuse, and one thing is that's kind of powerful about Shifty Y, is, because it's so declarative, reuse is basically an implementation detail. We really try to optimize things, and use reuse, or don't reuse reuse under the hood, to do the best result for your apps. So, I would really look at things like the performance instrument to figure out just what's expensive about your views, and what your app could do to make that better. Excellent. And again, I'd also call out the new instrument, which I'm so excited about. If you do think you're having some performance issues in scrolling, if you're seeing hitches, try it with the instruments, see if that helps you narrow it in on what the problem might be. So the next question, I'm gonna throw your way, Anna. This is from Amir. So, implementing the new iOS 26 tab bar, it seems to be very low contrast when there's darker content underneath the tab bar. Is there anything we should be doing to increase the contrast in our tool bars, or tab bars? Thank you for the question. Thank you for noticing that and thinking about that. I would say, honestly, the new design is still in beta. That would be a really awesome feedback to file. I would probably recommend, especially, like, it's in Beta right now, I would recommend against trying to modify, like, the standard system components, but I would, like, file a feedback so that we're able to take that into account, like, across the system for all apps. Yeah, and this is a great place to call out that, like, all of our apps on the platform have been adopting liquid glass, and so we're tuning the experience based on those, But this week is the opportunity to get all of your apps onto the new, onto the new design, and to see how they perform, and this much larger pool of apps, testing the system, is going to be a great way for us to make it better for you and for all of our shared customers. And so that feedback early this year is super important, and we're really looking forward to that. Yeah, and I think, especially when that feedback is around things like contrast or other accessibility issues, like, there's just such a wide matrix of different things that can happen in your apps and ours, and getting that to us is so, so valuable right now. Summer, let's stick with you for the next question. This one comes in from Nuno. Um, yes, or they ask, excuse me, um, if I'm starting a new multi platform app, so I'm, I'm going to deploy to iOS, iPad OS, Mac OS, for example, But I know that it's heavily going to depend on UI kit or abkit views for some of the core structures. So, using NS split view, or, you know, a UI collection view, et cetera, should I still use Swift UI to manage the app life cycle? What do I think about in making that choice? That's a really good question. And I would generally say yes, It's still gonna be a great foundation for you. And by using Swift UI, kind of as you're starting, point to handle the life cycle, it's gonna just make it easier when maybe you want to add some Swift UI components in the future, Or perhaps we add new components, and you're like, oh, I really want those, then you're gonna be setting yourself up for success to kind of quickly iterate using, because that lifecycle of management's all already there. But I imagine, actually, Taylor might have some more thoughts on this as well. I mean, everything that Summer said was totally true, and, like, this interoperability, um, has been at the core of Sufjuai from the very beginning. You know, we had a lot of the core APIs to go back and forth between 50 IUI gad advocate at the beginning, and every year, we add more, right? And I talked about the scene bridging, where, if you build part of your app and you realize you need to actually utilize, uh, you might interaptive life cycle, you can bring all the existing soup du icenes you've already built up into that app, or, or vice versa, so, it's really a core part of it that you should think of it, not as a binary choice, but as a mixing of whatever you need. Great advice, thanks. And I'm going to throw this next one to you. This question comes from David. David says, I'd love to know more about the match transition source API that you've added. Is it a native way to have elements more from a V stack to a sheet? On what's the use case for it? Lee, um, so, that would be, it's kind of, yeah, it's a good way to kind of, like, connect those different views, like, kind of, like, this year, you know, when you present, um, like, popovers or other presentations, like, out of, like, all bar items, it's kind of a way to, like, connect, like, what, like, your interaction to the thing that then it's showing. Like, I think for, like, a V stack to a sheet, yeah, it might be that, like, they're connected, or, for some reason, like, you're not, like, I'm thinking about it, like, maybe, like, someone's performing an action, and it's, like, making it go larger, So it's, like, zooming in and out. The other thing, I think, is super cool about, like, that transition, particularly, like, the zoom one, is it's, like, fully interactable when people can, like, swipe it. It just creates a really, really nice experience. And so we have support for that this year and tool bar items, and since last year, we've also supported that with just, like, normal views like your UV stock. Excellent. Thank you. Um, Nick, the next one, I'm gonna throw your direction. Um, so, this comes from Davidas, um, instant singleton, or environment object, purview models. What a great question. recommendation. Yeah, so who hasn't written public static lead shared, at least 10 times in the last year? But I see this a lot in client code. I see this a ton, and it, everyone's so familiar with it from kit days, but at the same time, in Swift UI, it really kind of makes, right off the bat, it makes your code more difficult to test. And then on top of that, the environment object is really trying to take care of that for you, so that the problem that's shared with solving in the past was getting at this singleton from anywhere. But with environment object that's not really a problem anymore, You put this object at the root of your hierarchy or wherever you need it, and then people use the environment APIs to access it. And so, shared isn't actively harmful, but it does make things more difficult, and it makes refactorings more difficult, and, uh, hopefully, that explanation kind of made sense, and you go, Remove one public static, let's share in front of your, uh, frame your code base. I think previews are another great example where, like, using environment object lets you kind of inject different contexts for different previews, um, to school. Um, Taylor, let's stick with you, uh, for the next question. Um, and this question comes to us from Andrew, um, Andrew asks, um, I've noticed with the new design language that SwiftUI've used appear to not use color as much. For example, color modifiers for list view items like carrots, is this intended? Can developers introduce color back into elements, if desired, like moving back to something like the iOS or iPad OS 18 style? Yeah, no, that's a great question, and I'd really honestly recommend watching some of the new design sessions this year that go into a lot of detail about sort of the design motivation, how to think about color. Um, I think it is true that in general, you know, the liquid glass takes advantage of what we call monochrome, uh, controls on top, and so I would avoid sort of, quote, arbitrary tinting of things, but tinting is super important to communicate things to the users of your app, you know, to draw attention to key actions, or to indicate a piece of state. And so the color is actually playing even, even bigger role, because it's indicating those things, as opposed to just visual visual flair. So I think it's kind of a cool opportunity to look at how exactly you use color and really make the most of it. Yeah, one thing folks will find, as, you know, they use the betas of the new operating systems, is that with liquid glass design, and the new design system, color really draws the eye, maybe more than it did before. And where before, we might have used color to indicate, here's an action. We have glass around buttons and controls now, and that indicates that this is an action. And so, if you introduce too much color with these bright, you know, beautiful glass elements, it's hard for people to concentrate, because it draws their eye too much. And so, this means that color is really powerful when you do want to draw someone into a particular area of your app or into a particular action, but you really have to be careful not to overwhelm people with too much color. And I'm going to throw the next question your direction. This comes from Michelle. What's the best way, in Swift UI, for a view to communicate values back to its parent, that cannot be overridden by the parent? Binding is not really suitable, because that allows the subview to right back to the superview. But what's the right way to think about doing that? Yeah, that's a really good question. I agree that binding does not sound like a very good tool for doing that. Um, but so if GI does have tools that enable you to, I think it partially depends on like what that parent actually is. So if that parent is a container, I would recommend taking a look at container values, which are these values that are able to be read by a container. And there's a really great WWDC talk last year from Matt on our team about that. And then if you are kind of just communicating it up, honestly, kind of, you want to go up instead of down like you might in the environment, I would take a look at preferences. So with preferences, they flow up, and then you'll implement something that kind of, if there are multiple preferences, deciding what you should do to go and combine those. So those won't get modified. unless you're doing, like, that reduce, and then also consider, like, using closures, that's particularly good, Like, if you need to perform an action, or also if, like, you may need to interrupt with some of the kit views like you, I kit or rap kit. Awesome, I'm gonna take this opportunity to shout out, um, our talk on rich text, and, um, attributed string. There's a amazing sample code project with that on using the new rich text editor, But one of the things that Max and Jeremy did in that is they used a preference that is passing the current selection up the view hierarchy, and then they have an inspector, and so you can highlight the name of an ingredient in a recipe, and in the sidebar, it shows up as something you can add to your ingredient list or your shopping list. It's just a great, real world code example of using preferences to communicate information. So I'd really encourage people to check that out, and check out that session video also, because it has a lot of fabulous Easter eggs that I think you'll enjoy. Oh, Gundland. So, Summer, I want to throw the next question, next couple of questions to you. So strap in. Um, this question comes from Evelyn, Thanks for the question, Evelyn. I saw that animations are available in widgets for Vision OS. Are they also available for widgets on iOS? Yeah, so the same animations, uh, things that are available on Widgets for, uh, for Vision OS have been supported on iOS. I think since 17, since iOS 17. So like tweaking animations for entry transitions and things like that, But if you want more information, there's a talk from wwdc 23, um, which is bring widgets to life, which is an awesome talk, And that's going to talk all about animated and interactive widgets for apps or for games or anything like that. So definitely recommend taking a look at that talk. Excellent, thanks. Continuing with you, Summer, This question comes from Fred. Is it possible to add hyperlinks to the text inside a rich text editor? Ooh, good question. I was just in this code, so this is very fresh in my mind. Yes, yes, you want to use the foundation's link attribute, so that's going to be like attribute scopes, foundation attributes, link attribute. And that's what you'll use to do that. But note, in seed one, there is a known issue that we are aware of, where the link gestures aren't behaving correctly. So that might be why you're asking this question. that is something we're aware of. Excellent, thanks. Um, and, uh... I appreciate that you've been in that code lately, Summer. It's a good time. It's very exciting when a manager gets to go into code. Like, wow. Big day. That is the most exciting thing, yeah. Thank you, Jay. Uh. So, Anna, I'm gonna throw the next question your way. This is from Bastille. What's the best way to implement custom tab bars in SwiftUI? Yeah, I mean, you have a few different options. I will just, like, preface this, and I'm going to sound like a broken record, but I would recommend taking a look at if you're able to use the standard system controls for what you're trying to build. So, like, we offer different APIs that allow you to customize things like the color or the label, or, like, there's a really cool one this year for, like, you know, showing, like, a separate search tab, kind of seeing if those will work for you, because then you get kind of the right appearance across, like, all of the operating systems prior to the new design, with the new design, if you are looking to do something that is, like, way more custom, and that's still what you're looking to do, I would take a look at, like, the new glass APIs, like glass effect container. I think that's the one that Nick was alluding to previously. and then, like, Glass Effect, and also the safe area bar, API, to be able to, like, build things that are a little bit more like what we have on the system. Excellent. Also, one other thing, file a feedback. If there's, like, some little thing where it's, like, if only you had this, I would be able to use it. Like, that's also really helpful feedback for us to know. Excellent. I appreciate that. Um, and I'm gonna stick with you for the next question. excuse me. This comes from Zack. Um, and I think we mentioned this up top, but, um, we mentioned a little bit about this up top, but, um, the question is, specifically, is there API to show the navigational link Chevron when there isn't a navigation link? But it's a regular button. Yeah, so there isn't an API right now. We would definitely be curious to hear more about your use case and, like, why, like, a button versus a NAV link for that. The other thing I will say is you can, um, read the indicator visibility out of the environment, and that is one thing that may be a helpful tool if you want to create, like, button like navigation links, just to be able to kind of align with the system defaults there. Yeah, and, um, I also point out that, um, the, uh, trailing chevron, um, SF symbol is what navigation links are styled as. And so there is an SF symbol for that, so it's to combine that in an image with that environment key that Anna mentioned. That gives you the pieces to build this. So, while there's not direct API, it's not too many steps to get there. The other thing I will say, this is, like, more of a polish detail, but if you have, like, your navigation link in some selectable container, also do consider, like, selection when you were doing that. Like, say, you have a button, and you have, like, a selectable list, you may want to make sure that, like, your selection state is aligned, 'cause, like, when you select a navigation link in Swift, UI, that does, like, show as selected when then it pushes. And it has that very subtle effect that shows us selected as you're coming back from whence you came, which is, like, you can see in mail. That is, uh, and that is a challenging thing to get right, as all of my colleagues who've worked on navigation can attest. Um, the next question I have to ask, just because of the developer's name, this question, this is really for anyone on the panel, but maybe we'll start with you, Taylor. This comes to us from Fruit Coder. Can you create custom components, like the tab bar, with a fluidly draggable glass droplet over them? I see, yeah. So, probably echoing, you know, what Anna said about, you know, using standard components in UCAN, and, you know, moving to building custom components when you need to. So there is, obviously, the new class effect API, which lets you build custom liquid glass components. I think you maybe are referring to this little lift up effect that appears when you change selection. There's currently not API for that, but do file feedbacks if you feel like you're having use cases where you want additional API for creating the effects you want in your custom controls. I think we always love to hear that of what people are trying to do, and trying to make. Yeah, and I'm gonna echo that. Sometimes we sound like a broken record, asking for feedback on things. But this comes back to the thing I mentioned earlier about how we see how developers within Apple are using the APIs, and that informs the design of the API, but we can't anticipate everything, like, our developer community is endlessly creative, And so getting feedback that has screenshots, or description of the use case, can really help us understand the full scope of all of our developer communities needs, so that the team can design API that is generally useful. Like, the team works very hard to build API that is simple and flexible and composable. And sometimes you just need a lot of input in order to understand what the use cases are, that that API has to cover. So that feedback is just invaluable to us, and we really appreciate it when folks can take the time to feed that file that. And I do love the name, too. Yes. Um, so the, uh, the next question, um, comes to us from Jeff, and Nick, I'm gonna, I'm gonna let you start on this one. but maybe we can throw it around the horn. Do you have any tips on how we can unit test our Swift UI views, like the way we did with our UI kit views, is there a way we can do that without the need of a third party library? Yeah. Uh. First of all, Jeff, thank you for this question. I think about this a lot. Bro, I think about this probably three times a day, every day. He really does. He really does. It's so important, and so important, and it's a tricky answer, and I can't give a prescriptive one that will kind of cover everybody's cases. So, I'll start off by saying that, if you think about where the majority of your bugs lie, in my experience, that's most often, or many times, in the business logic, and so, if you can catch those bugs in your business logic, there's no need to be directly testing that against your swift UI views, and that probably, generally, that even makes the test a little too comprehensive. Um, and testing not exactly what you're going for. And so that's one example, and I can give a concrete example of testing that, so a lot of people like to test login flows in their app, and that's a really important flow to test. And when you're working on that, you can kind of typically have your navigation stack, and you push from your username password field, into your next view, and you might be tempted to test that with, like, a snapshot test, where you check that that pushes. Um, but I would, I would challenge kind of that assumption and say maybe a better, or, a more testable architecture to take would be to put that data in a model, and test that when you populate, populate the username and password field of your model, and submit that, that now your navigation path contains, you know, home screen, and that is a really quick test, right? That test is executing in milliseconds, not seconds, in your CI system. So, that's one example. I wonder if any other panelists kind of have other favorite, favorite things to think about. Yeah, I think I would also say, like, there are some modifiers in Swift UI where, like, you are performing in, like, it's performing in action as a result, and kind of going off of what Nick was talking about previously, thinking about, Hey, how can you move that logic out of your views and into your models? So maybe it's, like, I'm trying to think of one, but, like, I don't know, on change of a particular value, you want to do something. Like, you may want to make it so that that's not, like, performing actions directly, but it's calling into a model or something else, so that then you're able to, like, unit test that separately, and not have to be, you know, in a swift UIV to do that. Yeah, beyond unit testing, like, I find that people who take, like, a hard look at what their relationship is with their model, versus their views, and really try to keep their views, you know, quite as small as possible, often end up with just better apps as well, like, beyond the unit testing, right? They have kind of a more understandable view hierarchy. They have kind of fewer bugs because they're able to do this unit testing, or they're just able to reconcile it a lot better. So I think it's a great question about unit testing, but a lot of these ideas just help your app at the end of the day, which is a really cool thing. Yeah, I think we try to design, and I think we do design our APIs in a way that's architecture agnostic, but I think I'm not saying anything too controversial. Oh, here, when I say, whatever architecture you pick, have a testable architecture, and, uh, that what Taylor just said is great, And it's tricky. It is tricky to get that right, but it's a great thought exercise, and it pays big dividends. Excellent, thanks. So the next question I want to address is coming to us from Sam, and Sam says, We're building an ultra high performance photo library grid view. Can't wait to see it, Sam. But Sam's question is, what's the recommended way to display thousands of thumbnails in a lazy V grid without dropping frames or showing empty cells as the asset thumbnails load in? What are some things we can do to improve that? Yeah, I mean, I think... Go ahead, Diana. I think the first thing I would say is, consider what work you need to be doing on the main thread versus what you can do, like, off of the main thread. There are some really, really great Swift concurrency talks this year that kind of talk about, in particular, I think, Kurt, you probably know the full name, but embracing Swift concurrency kind of takes you through that journey of, like, you start with everything on the main thread, and then you start, like, moving things off as you find, you know, your app needs it, the Swift UI performance instrument can be a great way to also figure out, like, are there issues with scrolling or other things that are happening because you're doing, um, a lot of work on there. The other thing I would say is, like, four high resolution images consider scaling them down to the display size, Just do the amount of work that the display needs, not more than that. But I'm curious if anyone else has thoughts on that. I'm never gonna resist it, another chance to plug the instrument, so I'm gonna jump in and say, the new instrument, I think, is great, 'cause the thing you want to watch out for is your view, initializers, or your view, bodies being too expensive, right? So any, like, image decoding work you're doing there really should be moved off, like Anna said, and the instrument can help reveal when maybe you're doing that when you didn't even realize. So, one plug for the instrument, curious if anybody else has other elaboration. One really... I'll Oh, go ahead, please. Uh, I just, I remember this demo from two years ago, when we were doing performance lists, a performance work, um, on list, and Hautian, who is a subtracting member, who just does amazing demos, did this demo where, uh, he visualized how fast cells were invalidating on the list, and you can typically do that with color, and so, uh, take your photos, give them a small inset, and give them a background, uh, and make that background color dot random. And so flick the scroll, you know, flick the list, and if you see an absolute disco ball, you're in trouble. right? Because all your photos are invalidating for reasons you don't know, and they shouldn't be. And so that's a great debugging technique. It's just that random background color to see what you're invalidating, and go from there. It's very appropriate that you mention the disco ball neck, I think. Is it right? Excuse me, Anna, I, uh, I appreciate the call out to, uh, to Doug's session, uh, on embracing, um, Swift concurrency. We also have a couple of follow up sessions on that. Um, SEMA did a session. It's a Codalong, elevate an app with swift concurrency, which looks like at specific techniques, for using concurrency to improve performance, and it's got this great corgi in it, so you should watch. And then Daniel also did a fabulous concurrency session. This explicitly about the concurrency annotations in the Swift UI framework, and how to understand what those annotations tell you about the behavior of Swift UI. And it's a really, to me, that was, because I understood Swift UI more than I understood concurrency before watching it, it was a great way for me to understand swift concurrency in the context of UI updates, which is something I am familiar with. So, strongly recommend that session, as well. So the next question I'm going to send your way, Summer, This is from our good friend, Paul. Is there any way to make date picker respect dynamic type? It seems to like to render itself at a small size, no matter what I do. Ah, yeah, this is actually a known issue. So there's currently isn't a way to customize it. But please, please file a feedback. Definitely an important and important one. Thanks, Summer. For sure. So the next one is a, is a tricky question, and I'm able to throw this one around the horn. Um, are there any, um, This comes from Marco. Um, and I'm gonna rephrase it a little bit, to make it more comfortable answer. But, um...One are some common anti patterns you see when folks are adopted. Let's start with you, Taylor. Yeah, the first one that comes to mind is, I think something that some people have heard of, like, conditional modifiers using gift statements. So some people, you know, want to say, Hey, sometimes this modifier should apply, and sometimes it shouldn't, and so they may be right a little rapper, that says, Okay, well, if conditioned, apply this modifier else, just don't apply the modifier and return some opaque view with that. And so, the problem that some people are probably aware of is that that changes the identity of the view, and so it causes the view to get kind of torn down and rebuilt, you not only can lose state or animations when that happens, but it's also just bad for performance, because it's not maintaining that view that you're using. Most modifiers have what we like to call inert variants. So, it actually has the ability to pass, you know, one dot, or zero dot, or nil, or something that says, Okay, this current modifier is not overwriting anything, it's currently in a state, which feels silly when you, like, if it's only that, but what that's meant for is, when you have this condition, so you can have, like, a turn area in there, or some computed variable, to say, Okay, well, in some conditions, the value is this inert value, and in some cases, it's the value you want, and that is the way to do it. Honestly, if you ever encounter a modifier where there's not this inert variant, we want to know about it. You know, those are things that we want to continue to fill in, if that doesn't exist. So, like Kurt was saying earlier, if you provide us that feedback, we know what you're looking for. We know what you need to do. We want you to avoid needing to use these kind of conditional modifiers, so to speak. Yeah, well, I'm gonna add some color to that, 'cause one thing I see when talking with developers is that coming from an imperative mindset, it's common to think about, like, well, if I put an if in here, I'm avoiding all this work, because I'm skipping over it. Um, but in, in Swift UI, it's declarative, we're collecting all of that information, and internally, we're optimizing. So if you're setting opacity to one based on some condition, well, we don't have to do any work there. And so, the system will automatically not do the work for you. And so the if is actually more expensive than using the inert modifiers. So let's continue our trip around the Horn. Nick, do you have a favorite or least favorite anti pattern that you've seen? Yeah, yeah, great, really great question, Marco. I think this is one of our favorite things to talk about. I've already covered public static, Let shared, right at the top there. Um, as kind of a smelly smell. Um, but one thing, uh, this is navigation specific, and, uh, one that I see quite a lot, and it also kind of, I think, comes from working in a, in a UI kit background, where we think about navigation, kit, or navigation stack, and U.I. navigation controller as, as two similar components. Um, allow me to paint a picture for a minute here. So you've got your navigation split view, your sidebar column, and your detail. And one thing people are always doing is they're using if statements or selection to declare and undeclare a navigation stack in that detailed column, and the way those APIs were designed is that that's supposed to be much more static. And so, a very concrete piece of code that I see all the time is, in their detail column, people will say, Here I go describing code in the air. People will say, um, if let's selection, navigation stack, else, you know, content unavailable view, And so, what that's doing is causing swift DI to do a lot of work every time you change your selection, or know your selection, because the, um, the stack will come and go, and come and go. And so we're laying that out, and all this stack is setting up and tearing down. And so, what you really want to do is have that navigation stack be the root view of your detail column, and then do all your view switching inside of there. So... Excellent. That is a great one, and maybe my favorite anti pattern, also, as it were. Um, Summer, do you have an anti pattern you'd like to share? Ah, that's a good one. I I'm gonna do the politician thing and do a slight pivot. This is less of an anti pattern and more, it's something I see developers often forget about. And this is something around accessibility. And so if you've been doing accessibility for a long time with the kids, with the AppKit or UI kit, you're very used to kind of these very defined APIs, like I set the label, I set the value, things like that. But in Swift UI, we have this idea of an accessibility representation. So very often, if you're doing more custom work, maybe custom style, custom controls, things like that, it can be tempting to want to just, like, label and value them as we always have. But there's this whole idea of accessibility representation, which is essentially a hidden view that lets the excessibility system, the accessibility system can use to generate accessibility elements that make a lot more sense for something. So it's this really cool way of saying, like, I've got something that I want to behave like a toggle, but maybe it's, like, not just not actually a Swift UI toggle or something. So it's something I see, like, very often forgotten when developers have questions like, oh, how do I make this accessible? It's like, ah, I have the perfect API for you. So that's my little pivot on this question and accessibility plug. Yeah, and I love that API. Yeah, it's, like, it makes the accessibility representation declarative using the same, you know, views that you use to describe the actual views that appear. And so, if I'm using a canvas to make some animation or something, I can describe what's inside that canvas, just using SwiftUI views, and the representable APIs. So cool. So that API will remove a whole view hierarchy and replace it with accessibility information from the point of view of the system. Yeah, essentially from the point of view of the accessibility system, it will just behave as the swift UI you put in the representation. Yeah. As somebody who's, like, not an expert in accessibility, I do love that APF for the reason Kirk described. It really democratizes it in a way, where, you know, as long as you kind of understand the concepts of views you work with every day, you can kind of apply that to make sure your app is just as accessible. It really cool. Yeah, I will highlight that you don't need to do that everywhere. If you're using standard, Swift UI views and controls, those are accessible, you know, automatically as you use them. So this is really, if you're going off that beaten path and using customizable things, it's a great API for that. Definitely. Anna, how about you? Do you have a favorite anti pattern? Well, Taylor took mine, so I have to come up with another one. Um, but I think I would say the one, just one thing to think about, and this is more of, like, instead of one particular pattern, it's just more, like, in general, with SwiftUI, Thinking about your state and state maintenance, one thing that I see with, like, when people are using, like, containers in Swift UI, is that, like, if you conditionally are switching between them kind of, like, what Nick was mentioning, so, like, say you have an if statement where you're going between, like, a navigation stack and no navigation stack, or, like, between a navigation stack and a navigation split view, um, if you change from one side of that if to the other, you're going to lose a lot of your state. And so, like, unless you're doing maintenance on your behalf. So, like, there are ways to work around that, like, say, you know, you elevate a lot of that out into your model and that can work for apps, But just being mindful of it, because it can cause some subtle things for your users that can be confusing, Like, hey, I resized my app, and I was scrolled here, and now I'm not scrolled here. Like, that is one thing to just be aware of when you are using if statements, and kind of just thinking in general about how you manage your statements with Dubai. Excellent. Thanks so much. Um, Nick, I'm gonna throw the next question, uh, to you, is from Tomas. Um, Tomas asked, in recent dub dub sessions about Swift UI, I notice something that looks like view models, I see observable and state being used. Are there any recommendations or best practices for app, architecture, when using Swift UI? When do we think about when do you stay versus an object and bindable? What's the right way to think about that? Another tough one, these are, these are challenging to answer because it really depends on everyone's app. Like, if you've worked on many, many apps, you see that just the structure of the team, or whether it's a client, you know, a very network dependent app, or whether it's an app, that you're, that you try to be very offline, and you, you know, runs great on an airplane, like, these are all things to take into account, and so that's why we really try to, like I said earlier, make Swift UI architecture agnostic. That said, lean into observable, right? We're very comfortable saying that. That is our model object, that is an extremely reusable component that we're put improvements to each and every year. And it's also perfectly compatible with imperative frameworks, as well. So, I'm sure other people have thoughts on this, too, so feel free to jump in there. I'm gonna take a minute to plug improvements to observable this year, and that make it easier to use observable objects from your imperative code also. which is really kind of up leveled, observable, and I saw earlier this week, a proposal on up leveling observable even more on the Swift forums. So, I don't have time to actively participate in the discussion threads on the Swift forums, like I'd like to. But it is a fun place to lurk and see what the compiler team has in store down the road, and to see what the community is interested in and pushing for. So I'd encourage folks to look at that also. Anyone else want to share thoughts on state management, and so on, in Swift UI? I think... Okay. Okay, Taylor. I was gonna kind of combine what Anna was describing a little bit before with what you said, Nick. Like, observable is a really powerful tool, particularly like the fine grained and validation. You know, one of the pitfalls people ran into, previously, with observable object, is they might, you know, put this at the very top of their app, and using a lot of views, and it caused many views to invalidate, you know, when you scrolled in your list that might invalidate the whole pain of your app, and observable, you know, first of all, helps intrinsically avoid that. But it lets you also still be more precise and think about what are those exact dependencies, Where should you use subservable and whatnot? So, underscoring that is this great tool to use. The other thing I will plug is it's, like, another, like, really, like, observable has gotten even more kind of, like, fine grained this year, just in terms of, like, when observable sends notifications, so that then, like, Swift UI will go and update a view on its behalf. That's gotten a little more specific, and that's just, like, really awesome for viewing validations and other things. As long as we're here on observable, this is a weird analogy, but, like, observable, it's got a pretty quick learning curve. You learn how to use it pretty quickly, but it also has a lot of more intense use cases, I guess, and better ways to hold it, and certain things to be aware of. And so, like, you don't want to have observable owning one big struct, You want it to having hold little things, and you want to make sure you know how to use Will set and did set. And when you really know all the ins and outs of observable, it's like, you watch someone use a hammer, and you can hit nails, or you watch someone use a hammer to do, like, 10 different things, and they're using the end of it, and using the other end of it, and use the butt of it to tap things into the wall, and so, there's all sorts of different ways to hold observable, and it's really powerful. Excellent, thanks. The next question comes to us from Steve, and I'm going to start with you, and then maybe go around the horn. Steve asks or says, I've developed a few techniques for debugging Swift UI code. Could you share some of the techniques that you use? And Steve's particularly interested in geometry reader and other layout logic, But I think we should, like, open this up. I'd love to hear, um, what debugging techniques, um, y'all use in Swift UI code. So, Anna, we'll start with you. Yeah, well, I debug Swift UI code all day for my job, so... This is a very good question. I would say one of the things that I find really helpful is, like, knowing why my view updated or what things caused it to invalidate. And one of the techniques that I can use is, like, the self print changes, just to know, like, why, like, what triggered my viewbody to update. Also, you can visualize certain things with a new instrument, but print changes was available, like, even before that. So that can be a really good tool. curious if anyone else has other things to add as we go around. Let's, uh... I'm very... Go ahead, please. Nick? Oh, go ahead. Summer and Taylor. I mean, I'm I'm kind of old school. I'm using just, like, standard stuff, break points, especially conditional break points are great. Using, like, using sound and color also, like Nick's technique, that's new for me, but I'm actually going to steal that with the whole, like, disco scrolling. Um, but yeah, I really I really like, um, just I'm like pretty old school there. But making a brickpoint make a sound, when it hits, can be really another nice way to track one views update, if you're someone who likes extra media and you're debugging experience. I don't know what it says about us summer, but I was literally gonna say, I'm old school, too. Like it says we're old. Break points are great. Honestly, I use, like, printy bugging, and I know that's, like, embarrassing to share, but, like, honestly, it's so interesting to, like, put these in different bodies and initializers of views, to see, like, what is this life cycle of how things are getting updated? Are there views being updated that I'm not expecting? You know, it might be in cases where it's tedious to jump through every single breakpoint. You can kind of get this big textual description of, Hey, these are all the views updating when you scroll on a list, or press a button, and you can kind of ask yourself, are all of these correct? Are all these what you expect? Yeah, yeah, I mean, I didn't know if I was allowed to say print debugging, but I do genuinely use it sometimes for that exact reason. Yeah, like, you probably don't want to leave that in your shipping code, but it can be really helpful when 'cause it's also, like, Swift UI, maybe, like, rendering your body, like, decently frequently, so if you just put a break point there, it's gonna be a lot of noise before you find something that you're interested in. I went out debugging, which is, uh, less condit, but, um, it's crazy how, like, that really gives you an understanding of what's going on, and I was talking to Tommy, another engineer on SwiftUI, uh, last week, and I forget what broke, but he had, it might have been, oh, my God, it was something just outrageous that was affected by, um, an appearance override, like dark mode versus light mode, and, And sometimes, you can't, like, these systems are very complicated, and there are a lot of moving parts, and sometimes, if you really want to distill, you know, what did I do that broke this? You just got to common stuff out and hope for the best. I like the worst answer, but... No, but I think it's like when you're in a big app, it's, like, you add something, and you're not sure, like, why it broke. Like, I would say, honestly, breaking it, like, Swift UI is a framework that's composed of a lot of different pieces that you can compose together. So kind of trying to find what's, like, smallest point where I actually see this still happening. So, like, if you're, you know, doing controls, maybe trying, like, something that's a little bit simpler, or if you're in navigation, like, maybe not using your whole app, but, like, just, like, a smaller hierarchy can help you isolate, like, what is the cause of the issue that you're seeing? At the risk of turning this into a life hacks podcast, I do want to drill in on some specific ways that you do a couple of things that we mentioned. We kind of throw self print changes around, like everyone knows it. But the spelling of that is kind of unique. This is a debug API that you can put inside the body of your views. And it's a method call, but if you just call the method, you're going to get an error from the compiler. So the way you have to spell it is let, underscore, equals, and this says ignore the result, then capital S self, because it's a method on the view type, then dot underscore print changes. And so, I hope that translates, and I apologize to our ASL interpreter, who had to try to share that with you. But that's how you do self print changes inside a view body. Another thing that Summer mentioned, and this is one of my absolute favorite techniques, if you set a break point, and then you go into the edit the properties on that break point, you can turn on a system sound to play when the break points hit. If you do that, and then you also tick the box that says, Continue after hitting the break point, what will happen is, it will just make a sound whenever it fires, but it doesn't stop. And so, I will sometimes put two different sounds on two different views, and just listen for the relative mix of those sounds while I'm scrolling, it tells me a bit about, like, which is the piece that's invalidating. And so, it's a really cool technique, and I would recommend wearing headphones or having your own office before you apply that. because I knew Russell was not happy with me when I was doing that without my headphones on. So the next question, let's start with, throw this to you to begin summer. This question comes from Zev. Is there an easy way to format text using markdown, but customize what font faces to use for bold or italics, or so on? I'm to match the design that our designers are looking for. Let's see, so, um, so, Swift UI applies, um, for markdown, Swift UI applies standard, bold metallic traits, um, to the font that you supply to the environment. But it sounds like you probably want something a little more custom. So, to go custom, you'll want to use foundations, attributed string, mark down, like parsing capabilities, which are built in. And then from there, you'll want to use your own custom logic to transform the inline presentation, inline presentation intent attribute. These are hard to say live, by the way. presentation, intent attribute. into Swift UI's font attribute. And so that's where your own custom logic from your designers is gonna come into play. whatever those in-line presentation intents means, you'll interpret them there. And then, to get it to text, you'll use text, attributed string based initializer, It's just like text, attributed string, and now it's now it's a swift UI text. But it's definitely a really interesting topic, so there is, I think we have an article on this called Instantiating Attributed Strings with Markdown syntax. And it's all about kind of how you get this all to work. But yeah, it's a great a great question and a great use case. So there's one question I'd like to ask y'all, and maybe we do rapid fire, because we are getting near the end, but, um, folks watching may have noticed that we have, um, presenters from the last five years of what's new in Swift UI with us on, uh, on the panel today. And so I'd like to go around and just ask each of you, um, what you liked most about presenting what's new in Swift UI for dub dub. And let's start with Anna, who did this year's session. I think it was honestly just, it was so amazing to get to learn about all of the work that, like, my teammates had been doing all year, and, like, get to share, like, represent all of that for everyone else. 'Cause it's, like, we try, as much as we can to stay up to date on all the proposals, but, honestly, there's a lot that's always new in Swift UI every year. So it being my job to get to, like, learn about all of that was fantastic. Awesome. How about you, Summer? It's the collaboration involved in that talk, so you just see two presenters on screen, but it's like, you know, so many people behind it. You know, you're reaching out to teams, getting demo, getting demo codes, getting screenshots, There's so much. And so the sheer collaboration, and particularly collaborating with Sam, my co presenter, was, like, one of the funnest experience. And you as well, Kurt, you were involved in that one. So, it was super fun. just the sheer collaboration of the talk. So I guess I'm next, if we're going reverse chronological, Jeff and I introduced you to the wonderful world of dog watching, And so the collaboration aspect was super cool. One of the other things that I liked about it is often working on a framework, you're implementing the pieces of the framework, and you don't get to actually use the framework as much. And so, I really enjoyed getting to, like, take all the API that my colleagues had built, and build little apps with it, and it was just super enjoyable. Nick, you're next. I hosted Swift UI's fourth birthday party. My favorite part about that session was making it fun. Fourth Perth, yeah, yeah. Just making it fun, and just kind of, you want to make it very approachable, and so, if you watch that session, there's a ton of stuff in the background. There's a fully baked cake, custom frosted with swift UI, and I believe in it, there's, like, a whole host of people who help put on the, you know, there's camera crew and audio crew, and directors, and I offered everybody a slice of this cake. and no one ate the cake, and so I had to take the cake home. And, like, eat all cake myself, so, um, I just like making it fun. That's wonderful. Taylor, how about you? Yeah, so, yeah, Matt and I were the first to share what's new and swift you. in the first years. And one of the most challenging but fun things to me, and that's true for, I think, every year, is there's so much that's new, right? And we can't talk about everything that's new. So it's really challenging, but fun, to figure out what are the things that we think people are gonna be the most excited about, and how do we form that into this story that makes so much sense? And I think every year, it's successful and every year, I love seeing how everybody makes it their own. So it's so exciting for me to see, every other year, getting better and better. So it's really great. Excellent. Um, I am afraid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment