Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

SwiftUI Documentation

Posts under SwiftUI subtopic

Post

Replies

Boosts

Views

Activity

A Summary of the WWDC25 Group Lab - SwiftUI
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 SwiftUI. What's your favorite new feature introduced to SwiftUI this year? The new rich text editor, a collaborative effort across multiple Apple teams. The safe area bar, simplifying the management of scroll view insets, safe areas, and overlays. NavigationLink indicator visibility control, a highly requested feature now available and back-deployed. Performance improvements to existing components (lists, scroll views, etc.) that come "for free" without requiring API adoption. Regarding performance profiling, it's recommended to use the new SwiftUI Instruments tool when you have a good understanding of your code and notice a performance drop after a specific change. This helps build a mental map between your code and the profiler's output. The "cause-and-effect graph" in the tool is particularly useful for identifying what's triggering expensive view updates, even if the issue isn't immediately apparent in your own code. My app is primarily UIKit-based, but I'm interested in adopting some newer SwiftUI-only scene types like MenuBarExtra or using SwiftUI-exclusive features. Is there a better way to bridge these worlds now? Yes, "scene bridging" makes it possible to use SwiftUI scenes from UIKit or AppKit lifecycle apps. This allows you to display purely SwiftUI scenes from your existing UIKit/AppKit code. Furthermore, you can use SwiftUI scene-specific modifiers to affect those scenes. Scene bridging is a great way to introduce SwiftUI into your apps. This also allows UIKit apps brought to Vision OS to integrate volumes and immersive spaces. It's also a great way to customize your experience with Assistive Access API. Can you please share any bad practices we should avoid when integrating Liquid Glass in our SwiftUI Apps? Avoid these common mistakes when integrating liquid glass: Overlapping Glass: Don't overlap liquid glass elements, as this can create visual artifacts. Scrolling Content Collisions: Be cautious when using liquid glass within scrolling content to prevent collisions with toolbar and navigation bar glass. Unnecessary Tinting: Resist the urge to tint the glass for branding or other purposes. Liquid glass should primarily be used to draw attention and convey meaning. Improper Grouping: Use the GlassEffectContainer to group related glass elements. This helps the system optimize rendering by limiting the search area for glass interactions. Navigation Bar Tinting: Avoid tinting navigation bars for branding, as this conflicts with the liquid glass effect. Instead, move branding colors into the content of the scroll view. This allows the color to be visible behind the glass at the top of the view, but it moves out of the way as the user scrolls, allowing the controls to revert to their standard monochrome style for better readability. Thanks for improving the performance of SwiftUI List this year. How about LazyVStack in ScrollView? Does it now also reuse the views inside the stack? Are there any best practices for improving the performance when using LazyVStack with large number of items? SwiftUI has improved scroll performance, including idle prefetching. When using LazyVStack with a large number of items, ensure your ForEach returns a static number of views. If you're returning multiple views within the ForEach, wrap them in a VStack to signal to SwiftUI that it's a single row, allowing for optimizations. Reuse is handled as an implementation detail within SwiftUI. Use the performance instrument to identify expensive views and determine how to optimize your app. If you encounter performance issues or hitches in scrolling, use the new SwiftUI Instruments tool to diagnose the problem. Implementing the new iOS 26 tab bar seems to have very low contrast when darker content is underneath, is there anything we should be doing to increase the contrast for tab bars? The new design is still in beta. If you're experiencing low contrast issues, especially with darker content underneath, please file feedback. It's generally not recommended to modify standard system components. As all apps on the platform are adopting liquid glass, feedback is crucial for tuning the experience based on a wider range of apps. Early feedback, especially regarding contrast and accessibility, is valuable for improving the system for all users. If I’m starting a new multi-platform app (iOS/iPadOS/macOS) that will heavily depend on UIKit/AppKit for the core structure and components (split, collection, table, and outline views), should I still use SwiftUI to manage the app lifecycle? Why? Even if your new multi-platform app heavily relies on UIKit/AppKit for core structure and components, it's generally recommended to still use SwiftUI to manage the app lifecycle. This sets you up for easier integration of SwiftUI components in the future and allows you to quickly adopt new SwiftUI features. Interoperability between SwiftUI and UIKit/AppKit is a core principle, with APIs to facilitate going back and forth between the two frameworks. Scene bridging allows you to bring existing SwiftUI scenes into apps that use a UIKit lifecycle, or vice versa. Think of it not as a binary choice, but as a mix of whatever you need. I’d love to know more about the matchedTransitionSource API you’ve added - is it a native way to have elements morph from a VStack to a sheet for example? What is the use case for it? The matchedTransitionSource API helps connect different views during transitions, such as when presenting popovers or other presentations from toolbar items. It's a way to link the user interaction to the presented content. For example, it can be used to visually connect an element in a VStack to a sheet. It can also be used to create a zoom effect where an element appears to enlarge, and these transitions are fully interactive, allowing users to swipe. It creates a nice, polished experience for the user. Support for this API has been added to toolbar items this year, and it was already available for standard views.
Topic: UI Frameworks SubTopic: SwiftUI
1
0
949
Jun ’25
IPad OS 16.1, Playgrounds and input fields
I have installed the latest beta on my iPad , iPadOS 16.1 (20B5050f) On running in app in Playgrounds that has a TextField, external keyboard input do not seem to be working. Tapping on the Text field inserts the cursor but no text can be entered on my external keyboard. (TextEditor field also do not work) Tested with both a Smart Keyboard and a Magic Keyboard. The keyboard works to enter the code in playgrounds, so it is not a keyboard connection issue. Disconnecting the keyboard, the onscreen keyboard is displayed and works correctly. Is this a Playgrounds issue or an iPadOS 16.1 issue or a compatibility issue with Playgrounds & iPadOS 16.1 ? import SwiftUI struct ContentView: View {     @State var field: String = "Test input"          var body: some View {         VStack {             Image(systemName: "globe")                 .imageScale(.large)                 .foregroundColor(.accentColor)             Text("Hello, world!")             TextField("", text: $field)                 .frame(height: 100)         }     } }
4
0
1.6k
43m
Capture a List selection AND push a view
I've got a situation where I want the iPad to push an editing view onto the sidebar (like on iPhone) and also display a detail view (no content view). This is working great. However, I need to determine which item from a List in a NavigationSplitView has been selected and pass this to the detail view (the selection is out of scope). This works with the List selection parameter, but the item selected is ONLY selected and the child view in the NavigationLink does not get pushed, nor does the detail view get changed. I either need to figure out a way to capture the selection without the List Selection parameter (Tap Gesture?) or get the navigation to happen even when using the Selection parameter. I'd appreciate some ideas as I'm a newb just learning SwiftUI.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
2
43m
Pickers in toolbar expand its width
With iOS 26 there has been a change in behavior with Pickers in the toolbar. The Picker looks expanded unlike other views such as a Button and Menu. See screenshots below. Is this the intended behavior or a bug? (I already submitted a feedback for this at FB19276474) What Picker looks like in the toolbar: What Button looks like in the toolbar:
0
0
26
6h
SwiftUI recursive list with children: programmatically expand nodes
I have a SwiftUI recursive list, created with the (children:) initializer, just like it's shown in the code example here: https://developer.apple.com/documentation/SwiftUI/List#Creating-hierarchical-lists I would like this tree view to be searchable (i.e a user enters a query into a text field and it searches the entire tree at all levels). Displaying a search result which is not at the top level would require its parents to be programmatically expanded. How to programmatically expand certain levels of such a list?
0
0
31
6h
Liquid Glass TabBar animations causes Hangs, bug with UIKitCore?
With iOS 26.1 we started seeing a bug that only appears on iPhone Air. This bug is visible with simulators too. I have tried so many different ways to fix the issue, but Instruments Profiler is pointing at UIKitCore. We load a tab bar, when the user attempts to switch a tab, the app hangs and never recovers. It happens right as the animation of the Glass bubble is in progress. I have tried a UIKit Tab bar, a SwiftUI Tab bar. I tore out AppDelegate and did a direct @main SwiftUI entry for my application. This issue appears with every tab bar instance I try. I attempted to disable LiquidGlass by utilizing this flag UIDesignRequiresCompatibility in my plist, but the flag seems to be ignored by the system. I am not sure what else to try. I have a trace file if that is helpful. What else can I upload? Here is what the code looks like. struct ContentView: View { @State private var selectedTab = 2 var body: some View { TabView(selection: $selectedTab) { Text("Profile") .tabItem { Label("Me", systemImage: "person") } .tag(0) Text("Training") .tabItem { Label("Training", systemImage: "calendar") } .tag(1) Text("Home") .tabItem { Label("Home", systemImage: "house") } .tag(2) Text("Goals") .tabItem { Label("Goals", systemImage: "target") } .tag(3) Text("Coach") .tabItem { Label("Coach", systemImage: "person.2") } .tag(4) } } } #Preview { ContentView() } and AppView entry point import SwiftUI @main struct RunCoachApp: App { var body: some Scene { WindowGroup { ContentView() } } }
6
1
316
21h
Preventing crashes with ScrollViewProxy.scrollTo()
I have a search field and a List of search results. As the user types in the search field, the List is updated with new results. Crucially, with each update, I want to reset the List's scroll position back to the top. To achieve this, I'm using the following .onChange() modifier along with a ScrollViewReader: .onChange(of: searchQuery) { _, newQuery in Task { searchResults = await searchLibrary(for: newQuery) scrollViewProxy.scrollTo(0, anchor: .top) } } My List uses index-based IDs, so scrolling to 0 should always go to the first item. The above code works, but crashes if searchResults is empty because there is no item in the List with an ID of 0. (As a side note, it seems rather excessive for the scrollTo() method to trigger a full-on crash just because the ID is not found; I don't think this should be anything more than a warning, or the method should throw an error that can be caught). To work around this, I added an isEmpty check, so we only attempt the scroll if the array is not empty: .onChange(of: searchQuery) { _, newQuery in Task { searchResults = await searchLibrary(for: newQuery) if !searchResults.isEmpty { scrollViewProxy.scrollTo(0, anchor: .top) } } } However, even with this check, I was seeing rare crashes in production, consistent with a race condition. My guess is that when searchResults is updated, the view is not recreated immediately, so if scrollTo() is called too quickly, the List may not yet be seeing the latest update to the searchResults array. I figured that I could try to delay the calling of scrollTo() to give the view time to update: .onChange(of: searchQuery) { _, newQuery in Task { searchResults = await searchLibrary(for: newQuery) if !searchResults.isEmpty { DispatchQueue.main.async { scrollViewProxy.scrollTo(0, anchor: .top) } } } } However, even with this, I've just received a crash report pointing to the same issue (the first in about four months). I'm not able to reproduce the bug myself – so it definitely seems like a rare race condition, probably relating to the timing of view updates. I guess, I can insert another isEmpty check before calling scrollTo(), but I'm starting to wonder if it's even possible to guarantee that the item will be in the List when scrollTo() performs its action, and because this is so hard to reproduce, I can't really test any ideas. Does anyone have any idea how (and at what point) the ScrollViewReader reads the view's current state? What's the right way to approach debugging a problem like this? Moreover, does anyone have any better suggestions about how to handle resetting the List position? The reason I want to do this is because, if the user types, scrolls a bit, and then types some more, the new results appear above the fold where the user can't see them, leading to a confusing experience. I thought about switching to the newer .scrollPosition() modifier, but that's only iOS 18+ and only for ScrollViews, not Lists. Cheers!
Topic: UI Frameworks SubTopic: SwiftUI
0
0
18
1d
Widget link broken by `.desaturated` image rendering mode
Using desaturated mode on an image in a widget will break any links or buttons that use the image as their 'label'. Using the following will just open the app as if there was no link at all - therefore just using the fallback userActivity handler, or any .widgetURL() urls provided. Link(destination: URL(string: "bug://never-works")!) { Image("puppy") .widgetAccentedRenderingMode(.desaturated) } The same goes for buttons: Button(intent: MyDemoIntent()) { Image("puppy") .widgetAccentedRenderingMode(.desaturated) } I've tried hacky solutions like putting the link behind the image using a ZStack, and disabling hit testing on the image, but they don't work. Anything else to try? Logged as Feedback #15152620.
8
5
784
1d
@state update not reflecting on UI.
I’m facing an issue in our native iOS app that occurs specifically on iOS 26.1 (not observed on any lower versions). When I update a @State field value, the UI does not reflect the change as expected. The @State variable updates internally, but the view does not re-render. This behaviour started after upgrading to iOS 26.1. Works fine on iOS 26.0 and earlier versions. Has anyone else encountered this issue or found a workaround? Any insights or suggestions would be greatly appreciated.
5
0
180
1d
tabBarMinimizeBehavior behavior in iOS 26
I'm trying to revamp the player into a floating style like Apple music. I use tabViewBottomAccessory with tabBarMinimizeBehavior. At the time, I noticed an issue that tabViewBottomAccessory would not automatically collapse when the scroll area was small (but still exceeded the screen height). tabViewBottomAccessory can only be automatically collapsed when the scroll area is large enough. Below is the simplest demo. I'm not sure if it's intentional or if it's a bug. Besides, I wonder if we can control it programmatically(expanded/inline)? struct ContentView: View { var body: some View { TabView { Tab("Numbers", systemImage: "number.circle") { List { // 200 works well, but 20 not ForEach(0..<200) { index in Text("\(index)") } } } } .tabBarMinimizeBehavior(.onScrollDown) .tabViewBottomAccessory { HStack { Text("SwiftUI Demo App") } } } }
1
0
99
1d
SwiftData @Query causes UI Hierarchy crash
Simple code like struct ContentView: View { @Query var items: [Item] var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() } } causes UI Hierarchy crash, on Simulators, iPhone and Mac I found no solution but use @State with fetch descriptor.
0
0
23
1d
How to improve my SwiftUI tvOS app flow?
Hello, I'm thinking about how to improve my main tvOS app flow, naively I want to do something like this: import Combine import SwiftUI enum AppState { case login, onboarding, main } class AppStateManager { let appStatePublisher = PassthroughSubject<AppState, Never>() func updateState(_ appState: AppState) } struct tvOSApp: App { private var appState: AppState = .login private let appStateManager = AppStateManager() var body: some Scene { WindowGroup { ZStack { switch appState { case .login: LoginView() case .onboarding: OnboardingView() case .main: MainView() } } .onReceive(appStateManager.appStatePublisher) { self.appState = $0 } } } } So basically, MainView, OnboardingView and LoginView would be the main navigation views of my app, and the appStateManager would be a dependency passed to each of these views and allowing me to update the currently displayed view in the app. (of course I could use an Environment object instead for a 100% SwiftUI solution). I was wondering, however, if there is a better way to do this, instead of switching in a ZStack, maybe with WindowGroup/Window/Scenes? Thank you for your help!
0
0
35
2d
How to disable highlight state on Link in LA widget
I am working on a Live Activity widget. In it, I want some of the elements to open different deeplink URLs. I have found that assigning multiple widgetURL doesn't work, only one of the URLs gets opened no matter where you tap. I also found that Buttons don't seem to do anything, tapping them actually just open my app as if I just tapped a naked Live Activity. I have found that really only Link elements work if I want to open different URLs upon tapping different elements. And Links are cool and fine, but I am seeing that on tap, my elements become tinted... As in, there is a highlighted state, and it makes the elements inside blue. I have tried to use button style API on a link, but it didn't work. How can I disable the highlighted state for a Link element in a live activity widget?
0
0
40
2d
Delete Confirmation Dialog Inside Toolbar IOS26
inline-code How do you achieve this effect in toolbar? Where is the documentation for this? How to make it appear top toolbar or bottom toolbar? Thank you! Here is what I have now... .toolbar { ToolbarItem(placement: .destructiveAction) { Button { showConfirm = true } label: { Image(systemName: "trash") .foregroundColor(.red) } } } .confirmationDialog( "Are you sure?", isPresented: $showConfirm, titleVisibility: .visible ) { Button("Delete Item", role: .destructive) { print("Deleted") } Button("Archive", role: .none) { print("Archived") } Button("Cancel", role: .cancel) { } } }
0
0
29
3d
SwiftUI: NavigationSplitView + Toolbar + Button = Constraint Warning
As the title says, when I try to add a Toolbar with a Button to my NavigationSplitView I get a warning about satisfying constraints. Here is a minimal reproducible example: import SwiftUI @main struct ViewTestingApp: App { var body: some Scene { WindowGroup { NavigationSplitView { Text("Sidebar") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button { debugPrint("Hello World!") } label: { Label("", systemImage: "flame") } } } } content: { Text("Content") } detail: { Text("Detail") } } } } This is the specific warning I get: Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x600002164960 h=--& v=--& _TtCC5UIKit19NavigationButtonBar15ItemWrapperView:0x100f80fa0.width == 0 (active)>", "<NSLayoutConstraint:0x600002160370 _TtCC5UIKit19NavigationButtonBar15ItemWrapperView:0x100f80fa0.leading == _UIButtonBarButton:0x100f7d360.leading (active)>", "<NSLayoutConstraint:0x6000021603c0 H:[_UIButtonBarButton:0x100f7d360]-(0)-| (active, names: '|':_TtCC5UIKit19NavigationButtonBar15ItemWrapperView:0x100f80fa0 )>", "<NSLayoutConstraint:0x600002160050 'IB_Leading_Leading' H:|-(2)-[_UIModernBarButton:0x100f7e6c0] (active, names: '|':_UIButtonBarButton:0x100f7d360 )>", "<NSLayoutConstraint:0x6000021600a0 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x100f7e6c0]-(2)-| (active, names: '|':_UIButtonBarButton:0x100f7d360 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x6000021600a0 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x100f7e6c0]-(2)-| (active, names: '|':_UIButtonBarButton:0x100f7d360 )> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. The project settings are all at their defaults, but in case anyone wants to try it with the whole project: https://github.com/OddMagnet/ViewTesting
Topic: UI Frameworks SubTopic: SwiftUI
3
0
89
3d
How do I prevent screenshots using SwiftUI?
Hi Team, How do I prevent screenshots using SwiftUI. I was using this solution on UIKit: extension UIView { func makeSecure() { DispatchQueue.main.async { let protectedView = UIView() self.superview?.addSubview(protectedView) // constraints... let secureView = SecureView() self.superview?.addSubview(secureView) // constraints... secureView.addSecureSubview(self) // constraints... } } } class SecureView: UIView { private lazy var secureField: UIView = { var secureField: UIView = UIView() // ... if let secureContainer = SecureField().secureContainer { secureField = secureContainer } ... return secureField }() required init() { ... } } Is it posible to do the same thing using SwiftUI. Do we have an example? What would you recommend when we work with confidencial information in SwiftUI like bank account information? Thanks in advance!
0
0
106
3d