Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

A Summary of the WWDC25 Group Lab - UI Frameworks
At WWDC25 we launched a new type of Lab event for the developer community - Group Labs. A Group Lab is a panel Q&A designed for a large audience of developers. Group Labs are a unique opportunity for the community to submit questions directly to a panel of Apple engineers and designers. Here are the highlights from the WWDC25 Group Lab for UI Frameworks. How would you recommend developers start adopting the new design? Start by focusing on the foundational structural elements of your application, working from the "top down" or "bottom up" based on your application's hierarchy. These structural changes, like edge-to-edge content and updated navigation and controls, often require corresponding code modifications. As a first step, recompile your application with the new SDK to see what updates are automatically applied, especially if you've been using standard controls. Then, carefully analyze where the new design elements can be applied to your UI, paying particular attention to custom controls or UI that could benefit from a refresh. Address the large structural items first then focus on smaller details is recommended. Will we need to migrate our UI code to Swift and SwiftUI to adopt the new design? No, you will not need to migrate your UI code to Swift and SwiftUI to adopt the new design. The UI frameworks fully support the new design, allowing you to migrate your app with as little effort as possible, especially if you've been using standard controls. The goal is to make it easy to adopt the new design, regardless of your current UI framework, to achieve a cohesive look across the operating system. What was the reason for choosing Liquid Glass over frosted glass, as used in visionOS? The choice of Liquid Glass was driven by the desire to bring content to life. The see-through nature of Liquid Glass enhances this effect. The appearance of Liquid Glass adapts based on its size; larger glass elements look more frosted, which aligns with the design of visionOS, where everything feels larger and benefits from the frosted look. What are best practices for apps that use customized navigation bars? The new design emphasizes behavior and transitions as much as static appearance. Consider whether you truly need a custom navigation bar, or if the system-provided controls can meet your needs. Explore new APIs for subtitles and custom views in navigation bars, designed to support common use cases. If you still require a custom solution, ensure you're respecting safe areas using APIs like SwiftUI's safeAreaInset. When working with Liquid Glass, group related buttons in shared containers to maintain design consistency. Finally, mark glass containers as interactive. For branding, instead of coloring the navigation bar directly, consider incorporating branding colors into the content area behind the Liquid Glass controls. This creates a dynamic effect where the color is visible through the glass and moves with the content as the user scrolls. I want to know why new UI Framework APIs aren’t backward compatible, specifically in SwiftUI? It leads to code with lots of if-else statements. Existing APIs have been updated to work with the new design where possible, ensuring that apps using those APIs will adopt the new design and function on both older and newer operating systems. However, new APIs often depend on deep integration across the framework and graphics stack, making backward compatibility impractical. When using these new APIs, it's important to consider how they fit within the context of the latest OS. The use of if-else statements allows you to maintain compatibility with older systems while taking full advantage of the new APIs and design features on newer systems. If you are using new APIs, it likely means you are implementing something very specific to the new design language. Using conditional code allows you to intentionally create different code paths for the new design versus older operating systems. Prefer to use if #available where appropriate to intentionally adopt new design elements. Are there any Liquid Glass materials in iOS or macOS that are only available as part of dedicated components? Or are all those materials available through new UIKit and AppKit views? Yes, some variations of the Liquid Glass material are exclusively available through dedicated components like sliders, segmented controls, and tab bars. However, the "regular" and "clear" glass materials should satisfy most application requirements. If you encounter situations where these options are insufficient, please file feedback. If I were to create an app today, how should I design it to make it future proof using Liquid Glass? The best approach to future-proof your app is to utilize standard system controls and design your UI to align with the standard system look and feel. Using the framework-provided declarative API generally leads to easier adoption of future design changes, as you're expressing intent rather than specifying pixel-perfect visuals. Pay close attention to the design sessions offered this year, which cover the design motivation behind the Liquid Glass material and best practices for its use. Is it possible to implement your own sidebar on macOS without NSSplitViewController, but still provide the Liquid Glass appearance? While technically possible to create a custom sidebar that approximates the Liquid Glass appearance without using NSSplitViewController, it is not recommended. The system implementation of the sidebar involves significant unseen complexity, including interlayering with scroll edge effects and fullscreen behaviors. NSSplitViewController provides the necessary level of abstraction for the framework to handle these details correctly. Regarding the SceneDelagate and scene based life-cycle, I would like to confirm that AppDelegate is not going away. Also if the above is a correct understanding, is there any advice as to what should, and should not, be moved to the SceneDelegate? UIApplicationDelegate is not going away and still serves a purpose for application-level interactions with the system and managing scenes at a higher level. Move code related to your app's scene or UI into the UISceneDelegate. Remember that adopting scenes doesn't necessarily mean supporting multiple scenes; an app can be scene-based but still support only one scene. Refer to the tech note Migrating to the UIKit scene-based life cycle and the Make your UIKit app more flexible WWDC25 session for more information.
Topic: UI Frameworks SubTopic: General
0
0
551
Jun ’25
No containerBackground content on Widget in iOS 18 tinted home screen style
The widget I have create for iOS 17 uses the containerBackground to display an image in the background. This works fine. But when I set the home screen to the iOS 18 tinted option the background disappears. I want the background to stay because it contains an image of that is meaningful to the user. I use the following code: @ViewBuilder var body: some View { if let memory = entry.memory, let uiImage = memory.image { Group { if entry.showCaption { memoryBody(with: memory) } else { Color.white.opacity(0.0000000001) } } .foregroundStyle(.white) .widgetBackground( Image(uiImage: uiImage) .resizable() .scaledToFill() ) } else if let memory = entry.memory { memoryBody(with: memory) .widgetBackground(Color.gray) } else { noMemoryBody() } } extension View { func widgetBackground(_ backgroundView: some View) -> some View { if #available(iOSApplicationExtension 17.0, *) { return containerBackground(for: .widget) { backgroundView } } else { return background(backgroundView) } } }
4
1
2.1k
Sep ’24
Square Notification Box
Apparently, the half-a-sec boxy notification issue remains up until now??? Please help fix the bug, Apple Dev. how come an issue from ios 16 still happening now in ios 18? reference: https://www.reddit.com/r/ios/s/Qx116rGBzM
Topic: UI Frameworks SubTopic: General
0
0
272
Sep ’24
This is an internal UIKit bug. Ignoring unexpected nonmatching counterpart: (null)
FB14569448 Since iOS 18 beta came out, our app has been failing at some point when a view controller is dismissed and it appears the main thread ends up looping in layout logic and logs the following to the console. The app hangs until it's terminated due to a memory overallocation issue. Anyone else seen this? <_UINavigationBarItemStackEntry: 0x302ac73f0> normalLayout[active]=0x1391ad880 searchLayout=0x0 item=<UINavigationItem: 0x13913a080> style=navigator: Ignoring unexpected nonmatching counterpart: (null) This is an internal UIKit bug. Snapshotting a view (0x1391e7c00, _UIButtonBarStackView) that has not been rendered at least once requires afterScreenUpdates:YES. frame #0: 0x000000019bb07000 libobjc.A.dylibobjc_msgSend frame #1: 0x00000001a0fb4224 UIKitCore-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededCollectingViews:forSecondPass:] + 144 frame #2: 0x00000001c270a030 CoreAutoLayout-[NSISEngine withBehaviors:performModifications:] + 84 frame #3: 0x00000001a0fe5424 UIKitCore__100-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededWithViewForVariableChangeNotifications:]_block_invoke + 120 frame #4: 0x00000001a0fe3ae0 UIKitCore-[UIView(AdditionalLayoutSupport) _withUnsatisfiableConstraintsLoggingSuspendedIfEngineDelegateExists:] + 112 frame #5: 0x00000001a0fe2b4c UIKitCore-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededWithViewForVariableChangeNotifications:] + 172 frame #6: 0x00000001a0fa9e90 UIKitCore-[UIView _updateConstraintsAtEngineLevelIfNeededWithViewForVariableChangeNotifications:] + 400 frame #7: 0x00000001a0fa9a18 UIKitCore-[UIView _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 312 frame #8: 0x00000001a0fa97a4 UIKitCore-[UIView(Hierarchy) layoutSubviews] + 204 frame #9: 0x00000001a124fa78 UIKitCore-[_UIButtonBarStackView layoutSubviews] + 56 frame #10: 0x00000001a0f6430c UIKitCore-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2492 frame #11: 0x00000001a029d8d0 QuartzCoreCA::Layer::layout_if_needed(CA::Transaction*) + 496 frame #12: 0x00000001a0fa81d0 UIKitCore-[UIView(Hierarchy) layoutBelowIfNeeded] + 300 frame #13: 0x00000001a1843fa4 UIKitCore-[_UINavigationBarTransitionContextCrossfade _prepareContentView] + 132 frame #14: 0x00000001a18443bc UIKitCore-[_UINavigationBarTransitionContextCrossfade prepare] + 84 frame #15: 0x00000001a184e59c UIKitCore-[_UINavigationBarVisualProviderModernIOS _performAnimationWithTransitionCompletion:transition:] + 1524 frame #16: 0x00000001a180f938 UIKitCore-[UINavigationBar _popNavigationItemWithTransitionAssistant:] + 220 frame #17: 0x00000001a180f5f8 UIKitCore-[UINavigationBar _popNavigationItemWithTransition:] + 224 frame #18: 0x00000001a13bec9c UIKitCore-[UINavigationBar _setItemsUpToItem:transition:] + 240 frame #19: 0x00000001a13be76c UIKitCore-[UIViewController _removeNavigationItemsFromNavigationController:transition:] + 232 frame #20: 0x00000001a19c9dc0 UIKitCore__89-[UINavigationController _immediatelyApplyViewControllers:transition:animated:operation:]_block_invoke_3 + 800 frame #21: 0x00000001a19d0b2c UIKitCore__98-[UINavigationController _shouldSkipHostedRefreshControlUpdateSchedulingDeferredUpdateIfNecessary]_block_invoke + 40 frame #22: 0x00000001a19d7574 UIKitCore-[UINavigationController transitionConductor:didStartDeferredTransition:context:] + 792 frame #23: 0x00000001a21c9600 UIKitCore-[_UIViewControllerTransitionConductor startDeferredTransitionIfNeeded] + 688 frame #24: 0x00000001a10ab040 UIKitCore-[UINavigationController __viewWillLayoutSubviews] + 84 frame #25: 0x00000001a1350bcc UIKitCore-[UILayoutContainerView layoutSubviews] + 172 frame #26: 0x00000001a0f6430c UIKitCore-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2492 frame #27: 0x00000001a029d8d0 QuartzCoreCA::Layer::layout_if_needed(CA::Transaction*) + 496 frame #28: 0x00000001a029d45c QuartzCoreCA::Layer::layout_and_display_if_needed(CA::Transaction*) + 148 frame #29: 0x00000001a02f64e0 QuartzCoreCA::Context::commit_transaction(CA::Transaction*, double, double*) + 472 frame #30: 0x00000001a02736c4 QuartzCoreCA::Transaction::commit() + 648 frame #31: 0x00000001a02b6584 QuartzCoreCA::Transaction::flush_as_runloop_observer(bool) + 88 frame #32: 0x00000001a1002c3c UIKitCore_UIApplicationFlushCATransaction + 52 frame #33: 0x00000001a10002dc UIKitCore_UIUpdateSequenceRun + 84 frame #34: 0x00000001a0ffff2c UIKitCoreschedulerStepScheduledMainSection + 172 frame #35: 0x00000001a1000df0 UIKitCorerunloopSourceCallback + 92 frame #36: 0x000000019e7edf90 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 frame #37: 0x000000019e7edf24 CoreFoundation__CFRunLoopDoSource0 + 176 frame #38: 0x000000019e7eba10 CoreFoundation__CFRunLoopDoSources0 + 244 frame #39: 0x000000019e7eac14 CoreFoundation__CFRunLoopRun + 840 frame #40: 0x000000019e7ea4c8 CoreFoundationCFRunLoopRunSpecific + 572 frame #41: 0x00000001eb06d1c4 GraphicsServicesGSEventRunModal + 164 frame #42: 0x00000001a1334a90 UIKitCore-[UIApplication _run] + 816 frame #43: 0x00000001a13e2d1c UIKitCoreUIApplicationMain + 340 frame #44: 0x000000010038ca7c LabWare Developmentmain at AppDelegate.swift:31:7 frame #45: 0x00000001c4f4e9b4 dyldstart + 2724
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
754
Sep ’24
What is ChronoKit.InteractiveWidgetActionRunner.Errors Code 1?
This is a follow up to this post about building a Control Center widget to open the app directly to a particular feature. I have it working in a sample app, but when I do the same thing in my full app I get this error: [[com.olivetree.BR-Free::com.olivetree.BR-Free.VerseWidget:com.olivetree.BR-Free.ContinueReadingPlanControl:-]] Control action: failed with error: Error Domain=ChronoKit.InteractiveWidgetActionRunner.Errors Code=1 "(null)" Google has nothing for any of that. Can anyone shed light on what it means? This is my control and its action: @available(iOS 18.0, *) struct ContinueReadingPlanControl : ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration(kind: "com.olivetree.BR-Free.ContinueReadingPlanControl") { ControlWidgetButton(action: ContinueReadingPlanIntent()) { Image(systemName: "book") } } .displayName("Continue Reading Plan") } } @available(iOS 18.0, *) struct ContinueReadingPlanIntent : ControlConfigurationIntent { static let title: LocalizedStringResource = "Continue Reading Plan" static let description = IntentDescription(stringLiteral: "Continue the last-used reading plan") static let isDiscoverable = false static let opensAppWhenRun: Bool = true @MainActor func perform() async throws -> some IntentResult & OpensIntent { let strUrl = "olivetree://startplanday" UserDefaults.standard.setValue(strUrl, forKey: "StartupUrl") return .result(opensIntent: OpenURLIntent(URL(string: strUrl)!)) } } Note also that I'm pulling this from Console.app, streaming the logs from my device. I don't know of a way to debug a Control Center widget in Xcode, though this thread implies that it's possible.
2
0
692
Sep ’24
External Display with SwiftUI in 2024
What is current best-practice for supporting an external display in a SwiftUI iOS app in 2024? (I'm only interested in iOS 17 and/or iOS 18) The only docs I found require abandoning the SwiftUI App structure and "switching back to a full UIKit App Delegate". Is this still the only option? Are there any complete examples on how to accomplish this? Also is testing external displays with Simulator at all reliable? All experiences I read about say that it never works. Thanks in advance.
0
0
338
Sep ’24
UITextView changed sequence of views in iOS 18
UITextView changed the sequence of views and on the top UIView. As a result in the custom gesture class in "touchesBegan" method, this code brings me "let touchedView = touches.first?.view" type of view UIView but it must be my own custom class type. How can I get a tapped type of view? Help please override func touchesBegan(_ touches: Set, with event: UIEvent) { super.touchesBegan(touches, with: event) let touchedView = touches.first?.view }
1
0
388
Sep ’24
iOS 18 navigationBar color scheme not working
Hello, I'm encountering an issue with toolbarColorScheme in iOS 18. In a simple example, toolbarColorScheme works fine when triggered in onAppear. However, after navigating to a different view (e.g., following a link, such as link 234), and then returning, the toolbarColorScheme seems to be ignored. Could anyone help me resolve this issue? struct TestNavigationBarColor: View { var body: some View { NavigationStack { List { Text("123") NavigationLink(value: 1) { Text("234") } } .toolbarColorScheme(.dark, for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .navigationTitle("Title1") .navigationDestination(for: Int.self) {_ in List { Text("Nested screen") } .navigationTitle("Title2") } } } }
1
0
854
Sep ’24
After interacting with a button in the live activity, the Control widget and home screen widget did not update.
I have a button on a live activity, and I want to end the live activity and update the Control Center widgets and home screen widgets after clicking this button. So, in the perform() method of the button's LiveActivityIntent, I called the methods ControlCenter.shared.reloadAllControls() and WidgetCenter.shared.reloadAllTimelines(), but they didn't work. Home screen widgets and Control Center widgets do not refresh, resulting in a poor user experience.
1
0
415
Sep ’24
.searchable bug with new navigationTransitions
When using the new .navigationTransition feature, when using .searchable at the same time result in the search bar disappearing when dismissing the view you've trasition to, has anyone else experienced this or found any workarounds? Here is an example that make the issue always occur. @State private var searchText: String = "" @Namespace private var namespace let things: [String] = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirdteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"] var body: some View { NavigationStack { ScrollView { LazyVStack(spacing: 20) { ForEach(things, id: \.self) { thing in NavigationLink(){ SwiftUIView(thing: thing, name: namespace) }label: { Text(thing) } .matchedTransitionSource(id: thing, in: namespace) } } } .searchable(text: $searchText) .navigationTitle("My List") .navigationBarTitleDisplayMode(.inline) } } } struct SwiftUIView: View { var thing: String var name: Namespace.ID var body: some View { Text(thing) .navigationTransition(.zoom(sourceID: thing, in: name)) } } After running the code you end up with this: And after clicking an element and dismissing it your get this:
2
0
370
Sep ’24
Scene Delegate Migration Lifecycle
We are in the process of migrating our application to SceneDelegate. We currently check in a variety of places if the app is running in the background for analytics reasons. The app may be running in the background due to location updates, notifications being received, or background refresh. With scene delegate, the app starts in the background state and only becomes active once a scene has connected. We have been unable to find a way if an app is truly running in the background or if a scene delegate is about to be launched.
Topic: UI Frameworks SubTopic: UIKit
2
0
449
Sep ’24
Live Activities Random Loading Spinner
Somewhat rarely, but often enough to be a problem, our live activities will entirely lock up with a frozen progress spinner and a dimmed appearance. We cannot figure out what this spinner means nor how to avoid it as it is not documented anywhere. No logs appear in Xcode nor in Console.app. We have more frequent updates enabled and are sending an update maybe once every 2 minutes, nothing that should cause us to exceed our quota. We cannot reproduce in a debugger Can we get some guidance on how to avoid this?
9
4
1.2k
Sep ’24
TabView more tab has double navigation bar when there's more than five tabs
When there are more than 5 tabs in TabView, the tabs from the 5th and on get put in the "More" tab as a list. But when each tab has its own NavigationStack, the tabs in "More" would have double navigation bars. The expected behavior is there should be only one navigation bar, and NavigationStack for tabs in "More" should be collapsed with navigation for the "More" tab itself. Minimal reproducible case: Run the code below as an app Navigate to "More" tab Navigate to "Tab 5" or "Tab 6" You can see there are two navigation bars stacked on top of each other struct Item: Identifiable { let name: String var id: String { name } } @main struct TestApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { let items = [ Item(name: "Tab 1"), Item(name: "Tab 2"), Item(name: "Tab 3"), Item(name: "Tab 4"), Item(name: "Tab 5"), Item(name: "Tab 6"), ] var body: some View { TabView { ForEach(items) { item in NavigationStack { List { Text(item.name) }.navigationTitle(item.name) }.tabItem { Label(item.name, systemImage: "person") } } } } } Before iOS 18, I can get around this issue by making my own "More" tab. But now with the expectation that user can re-arrange the tabs and all tabs would show up in the sidebar, the "make my own more tab" approach no longer work very well.
3
1
753
Sep ’24
Switching from Dark to Light mode does not update the background of `TabView` in SwiftUI,
Since iOS 18 I have noticed a strange issue which happens to the TabView in SwiftUI when you switch from Dark to Light mode. With this code: import SwiftUI struct ContentView: View { var body: some View { TabView { List { ForEach(0..<100, id: \.self) { index in Text("Row: \(index)") } }.tabItem { Image(systemName: "house") Text("Home") } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } The TabBar does not switch colours when going from dark to light, it work correctly when going from light to dark. Here is a video of iOS 18 with the issue: Here is a video of iOS 17.5 with same code and no issue: On real device it looks (better), the color does update but with delay. I have submitted a feedback bug report, but in the meanwhile has anyone been back to resolve this?
2
3
419
Sep ’24
SignInWithApple / AuthenticationServices fails SwiftUI
Xcode 15.2, iOS 17.2 I have a piece of code that displays videos. It has been working for at least 6 months. Suddenly only the first video played. The following videos would only play audio with the video being frozen at the first frame. I noticed that SwiftUI would start to instantiate multiple instances of my player observable class instead of just one. After chasing the problem for most of a day I found that if I completely removed every piece of code referencing AuthenticationServices then everything would work fine again. Even if I add the following piece of code which is not used or called in any way. Then SwiftUI will start to act weird. func configure(_ request: ASAuthorizationAppleIDRequest) { request.requestedScopes = [.fullName, .email] } If I comment out request.requestedScopes = [.fullName, .email] everything works fine. The SignInWithApple is configured and works fine if I enable the code. Any suggestions on how to solve or any work arounds would be highly appreciated.
1
0
945
Sep ’24
Tapping a TextKit 2 backed UITextView moves the caret to a random location
With the upcoming launch of Apple Intelligence and Writing Tools, we've been forced to migrate our text editing app to TextKit 2. As soon as we released the update, we immediately got complaints about incorrect selection behaviour, where the user would tap a word to begin editing, but the caret would be shown in an undefined location, often dozens of paragraphs below the selected content. To reproduce: Create a UITextView backed by a standard TextKit 2 stack and a large amount of text (50,000+ words) - see sample project below Scroll quickly through the text view (at least 20% of the way down) Tap once to select a position in the document. Expected: The caret appears at the location the user tapped, and UITextView.selectedRange is the range of the text at the location of the tap. This is the behaviour of TextKit 1 based UITextViews. Actual: The caret is positioned at an undefined location (often completely off screen), and the selectedRange is different to the range at the location of the tap, often by several thousand. There is no pattern to the magnitude of the discrepancy. This incorrect behaviour occurs consistently in the sample project on the simulator, but you may need to hide the keyboard by pulling down, then repeat steps 2-3 a few times. This happens on iPhone and iPad, and on iOS 17, 18, and 18.1. Do you have any insight into why this might be happening or how to work around this issue? Sample code is here: https://github.com/nathantesler/textkit2-issue/tree/master
2
0
683
Sep ’24
MapkitJS browser errors related to Place ID functionality
Hello, I am building a web app using Mapkit JS, and have something up an running where I can add markers and annotate places with Place ID (I followed along with the WWDC24 video). However occasionally, while I'm doing nothing on the browser, I get an runtime error with the following error trace (from developer tools in Chrome). === Uncaught TypeError: Cannot read properties of null (reading 'tint') at get tint (mapkit.core.annotations.d43c86.js:2:97102) at get colorScheme (mapkit.core.annotations.d43c86.js:2:81602) at e.exports.PlaceCardController._renderPlaceIframe (mapkit.core.map.536988.js:2:214785) at e.exports.PlaceCardController.update (mapkit.core.map.536988.js:2:212978) at e.exports.PlaceCardController._handleConfigChanged (mapkit.core.map.536988.js:2:213284) at _handleConfigChangedListener (mapkit.core.map.536988.js:2:212679) at n.dispatchEvent (mapkit.core.js:2:16624) at mapkit.core.js:2:10799 === It is completely random, and not a result of any browser / Map interaction. Seems to be an issue in mapkit.core, and related to Place IDs. Can anyone help with this?
1
0
668
Sep ’24
AccessorySetupKit - Removing accessory inconsistencies
Hello everyone, I am using the new AccessorySetupKit, and whenever I try to remove an accessory I sometimes get an alert asking me to make sure if I want to remove the accessory from my device. The problem is that this alert sometimes shows up, and sometimes it does not. The removal of the accessory does work, it is just that the alert is not predictable. Is this expected behavior? How can we “predict” when it will show up and when it will not?
0
0
444
Sep ’24
Help understanding `SwiftUI.App` identity lifecycle and need for `SwiftUI.State`?
Hi! I have a stateful object that should be created in my app entry point and delivered through my component graph: @main @MainActor struct MyApp : App { @State private var myAppState = MyAppState() var body: some Scene { ... } } The MyApp is a struct value type… in a SwiftUI world that seems to imply it could "go away" and be recreated as the system sees appropriate. We see this with view components all the time (hence the State wrapper to help preserve our instance across the lifecycle of our identity)… but I'm wondering if this State wrapper is even necessary with an App entry point. Could this struct ever go away? Would there be any legit reasons that this struct should go away and recreate over one SwiftUI app lifecycle (other than terminating the app and starting a whole new process of course)? And what lifecycle is the SwiftUI.State tied to in this example? In a view component our SwiftUI.State is tied to our component identity. In this example… we are tied to app component identity? Is there ever going to be multiple legit app component identities live in the same process? I'm thinking I could just go ahead and keep using State as a best practice… but is this just overkill or is there a real best practice lurking under here? Any more ideas about that? Thanks!
2
0
385
Sep ’24