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
615
Jun ’25
iOS26+ CNContactViewController will duplicate phone numbers and email addresses if an Avatar image is attached when creating the contact
Using the ContactUI framework CNContactViewController(forNewContact contact: CNContact?) to add a new contact to the ContactStore. If the new contact does not have an attached image then the contact is saved correctly. If the new contact DOES have an attached image then all entries in the phoneNumbers or emailAddresses array are doubled when written to the contactStore. Viewing the contact via the Contacts app shows the duplications. This is only happening on iOS26+. Earlier versions of the operating system do not show duplicates. Has anyone else seen this issue? Feedback reference: FB20910502
2
0
174
4m
Spotlight Shows "Helper Apps" That Are Inside Main App Bundle That Are Not Intended to Be Launched By The User
I have Mac apps that embed “Helper Apps” inside their main bundle. The helper apps do work on behalf of the main application. The helper app doesn’t show a dock icon, it does show minimal UI like an open panel in certain situations (part of NSService implementation). And it does make use of the NSApplication lifecycle and auto quits after it completes all work. Currently the helper app is inside the main app bundle at: /Contents/Applications/HelperApp.app Prior to Tahoe these were never displayed to user in LaunchPad but now the Spotlight based AppLauncher displays them. What’s the recommended way to get these out of the Spotlight App list on macOS Tahoe? Thanks in advance.
3
0
55
39m
NSButton + TtGC6AppKit18_NSCoreHostingViewVS_12AppKitButton - Image Alignment Changed/Broken in Minor macOS 26.1 Update
I just updated to macOS 26.1. I have a pure AppKit app (I guess that's not possible anymore but as close to a pure AppKit app as you can get). I use NSButton with the glass bezel style and SF symbol images. It looks like the minor OS update brought layout changes because now some of these buttons are scaling the symbol image much larger than was being done on macOS 26. The image can sometimes draw outside the glass 'bezel'. It looks like using the 'info' symbol in a button results in much larger image scaling than it did on the previous Tahoe for some SF Symbols. With the glass bezel style and a SF Symbol image how am I supposed to consistently make the button look good? With certain symbols I have to use imageScaling NSImageScaleProportionallyUpOrDown and on others I have to use NSImageScaleProportionallyDown. If I'm using a system image shouldn't it just do the right thing? Is trial and error the only way to tell? That's what I was doing before but it seems that the minor 26.1 update changed things. Additionally calling -sizeToFit on a button multiple times can cause it to shrink for example: [button sizeToFit]; // <-- At fitting size // Then later [button sizeToFit]; // Now button is shrunk But if the button is already at its fitting size an additional call later shouldn't make it shrink, it should stay the same size. FB20517174 I see I now inherit SwiftUI, not sure if that has anything to do with this but if I wanted to opt in to fragile layout I wouldn't be using Appkit...
1
0
26
1h
proxy.ScrollTo Unitpoint Y Value uses negative tenths for positioning?
I am using a ScrollViewReader, ScrollView, LazyVStack to organize a list of elements I want to be able to scroll to a specific location so i use elementID in the list and a UnitPoint value. But the y value for unitpoint uses -0.1 to represent 100%. Is this intended behavior, a bug, or am i using something incorrectly? I could not find this in the docs and it was only after debugging I found that proxy.scrollTo(id, UnitPoint(x:0, y:-0.1)) is how you scroll to the end of an item or proxy.scrollTo(id, UnitPoint(x:0, y:-0.05)) to scroll to the center. Am I accessing the scrollTo property wrong or is this just how we use it? Also it seems .bottom is broken due to this aswell (as it uses 1 but the actual value that scrolls to the bottom is -0.1). This seems like unintended behvaior as UnitPoints are supposed to be have values of 0-1 Here is a view which reproduces this behavior struct ScrollTestView: View { @State private var scrollToId: String = "" @State private var scrollToAnchorY: String = "0.0" @State private var scrollProxy: ScrollViewProxy? var body: some View { VStack { HStack(spacing: 12) { TextField("Enter ID (1-30)", text: $scrollToId) .frame(width: 120) .padding(8) .background(Color.gray.opacity(0.1)) .cornerRadius(8) TextField("Anchor Y (0-1)", text: $scrollToAnchorY) .frame(width: 120) .padding(8) .background(Color.gray.opacity(0.1)) .cornerRadius(8) Button { guard let targetId = Int(scrollToId), let anchorY = Double(scrollToAnchorY), let proxy = scrollProxy else { return } let anchorPoint = UnitPoint(x: 0.5, y: anchorY) proxy.scrollTo(targetId, anchor: anchorPoint) } label: { Text("Scroll") .font(.subheadline) .padding(.horizontal, 16) .padding(.vertical, 8) .background(Color.blue) .foregroundColor(.white) .cornerRadius(8) } Spacer() } .padding(.horizontal, 16) .padding(.vertical, 8) ScrollViewReader { proxy in ScrollView { LazyVStack { ForEach(1...30, id: \.self) { itemId in VStack { HStack { Text("Item \(itemId)") .font(.title2) .bold() Spacer() } .padding(.vertical, 16) Divider() .background(Color.gray.opacity(0.6)) } .id(itemId) } } .padding() } .onAppear { scrollProxy = proxy } } } } }
0
0
16
3h
AppKit Logging Internal inconsistency Errors on NSMenu on macOS 26.1
Appkit starting logging these warnings in macOS 26.1 about my app's MainMenu. **Internal inconsistency in menus - menu <NSMenu: 0xb91b2ff80> Title: AppName Supermenu: 0xb91a50b40 (Main Menu), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: () believes it has [<NSMenuSubclassHereThisIsTheMenuBarMenuForMyApp:] 0xb91a50b40> Title: Main Menu Supermenu: 0x0 (None), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( ) as a supermenu, but the supermenu does not seem to have any item with that submenu ** I don't what that means. The supermenu is the menu that represents the menu used for my app's menu bar (as described by NSMenuSubclassHereThisIsTheMenuBarMenuForMyApp Everything seems to work fine but log looks scary. Please don't throw!
Topic: UI Frameworks SubTopic: AppKit Tags:
1
0
25
3h
Drawing a PaperMarkup synchronously
The PaperMarkup class in PaperKit allows for an asynchronous function called .draw(in:, frame:) that we should call as: await paperMarkup.draw(in: context.cgContext, frame: rect) In PencilKit the PKDrawing that we can get from a PKCanvasView allows for .image(from: ,scale:) to be called synchronously. This allows me to easily render into a PKDrawing as a UIImage or a SwiftUI Image to, for example, render a thumbnail on screen. When trying to incorporate PaperKit in my project I noticed that I often need the drawing to be rendered synchronously (like I would with PKDrawing) but I can't find the way to accomplish this within PaperKit's current functionality. Is there any way to call .draw(...) in PaperKit synchronously? Feedback: FB20993683
1
0
33
4h
popoverTips don't display for toolbar menu buttons in iOS 26.1
[Also submitted as FB20756013] A popoverTip does not display for toolbar menu buttons in iOS 26.1 (23B5073a). The same code displays tips correctly in iOS 18.6. The issue occurs both in the simulator and on a physical device. Repro Steps Build and run the Sample Code below on iOS 26.1. Observe that the popoverTip does not display. Repeat on iOS 18.6 to confirm expected behavior. Expected popoverTips should appear when attached to a toolbar menu button, as they do in iOS 18.6. Actual No tip is displayed on iOS 26.1. System Info macOS 15.7.1 (24G231) Xcode 26.1 beta 3 (17B5045g) iOS 26.1 (23B5073a) Screenshot Screenshot showing two simulators side by side—iOS 18.6 on the left (tip displayed) and iOS 26.1 on the right (no tip displayed). Sample code import SwiftUI import TipKit struct PopoverTip: Tip { var title: Text { Text("Menu Tip") } var message: Text? { Text("This tip displays on iOS 18.6, but NOT on iOS 26.1.") } } struct ContentView: View { var tip = PopoverTip() var body: some View { NavigationStack { Text("`popoverTip` doesn't display on iOS 26.1 but does in iOS 18.6") .padding() .toolbar { ToolbarItem(placement: .topBarTrailing) { Menu { Button("Dismiss", role: .cancel) { } Button("Do Nothing") { } } label: { Label("More", systemImage: "ellipsis") } .popoverTip(tip) } } .navigationTitle("Popover Tip Issue") .navigationBarTitleDisplayMode(.inline) } } }
2
2
101
5h
How to check if a sandboxed app already has the access permission to a URL
I want to check whether a sandboxed application already has access permission to a specific URL. Based on my investigation, the following FileManager method seems to be able to determine it: FileManager.default.isReadableFile(atPath: fileURL.path) However, the method name and description don't explicitly mention this use case, so I'm not confident there aren't any oversights. Also, since this method takes a String path rather than a URL, I'd like to know if there's a more modern API available. I want to use this information to decide whether to prompt the user about the Sandbox restriction in my AppKit-based app.
1
0
21
6h
NSScrollView scrolling hitch
When scrolling a basic NSScrollView there seems to be a sudden jump after each flick. Scrolling does not appear smooth and is disorientating. A scroll jump seems to happen directly after letting go of a scroll flick using a trackpad/mouse. Right at that moment the scroll turns into a momentum scroll, slowly decreasing the speed. But the first frame after the gesture the content jumps forward, more than what is expected. Observations: Counterintuitively, scrolling appears to be smoother when disabling NSScrollView.isCompatibleWithResponsiveScrolling. If disabled using a custom NSScrollView subclass there is no large jump anymore. Scrolling also appears to be smoother using a SwiftUI ScrollView. I assume that has the same behaviour as a disabled isCompatibleWithResponsiveScrolling Ironically a WKWebView scrolls much smoother. No sudden jump is observable. It also seems to scroll with faster acceleration, but the individual frames do appear smoother. Why is this better than a native NSScrollView? Elastic scrolling at the bounds of the scroll view also appears much smoother for WKWebViews. When pulling to refresh there is a jump for NSScrollView/SwiftUI, but not for WKWebView. When using an NSScrollView with isCompatibleWithResponsiveScrolling disabled, scrolling appears just as smooth as WKWebView on macOS 13 Ventura and below. On macOS 14 Sonoma scrolling behaviour is suddenly different. Please see a sample project with 4 different scroll views side by side: https://github.com/floorish/ScrollTest Screen recordings show the sudden jumps when scrolling and when elastic scrolling. Tested on Intel & Arm Macs, macOS 11 Big Sur through 15 Sequoia, built with Xcode 16. Should isCompatibleWithResponsiveScrolling be disabled on Sonoma+? Are there any drawbacks? There is also no overdraw anymore since Monterey, as described in https://developer.apple.com/library/archive/releasenotes/AppKit/RN-AppKitOlderNotes/#10_9Scrolling Even with responsive scrolling disabled, why is WKWebView scrolling much smoother than NSScrollView?
Topic: UI Frameworks SubTopic: AppKit Tags:
7
2
644
6h
Modal presentation of SwiftUI view with TextField leads to frozen UI, missing keyboard and memory leak
Hello, I’m trying to present my custom SwiftUI dialog with text field in UIKit with modalPresentationStyle = .overFullScreen, but it leads to the UI being completely frozen once I select the TextField and memory constantly leaking. The minimal reproducible code is: class ModalBugViewController: UIViewController { var hostingController: UIHostingController<Content>! struct Content: View { @State private var text = "" var body: some View { ZStack { Color.black.opacity(0.5).ignoresSafeArea() VStack { TextField("Test", text: $text) .textFieldStyle(.roundedBorder) .padding() } } } } override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .clear hostingController = UIHostingController(rootView: Content()) addChild(hostingController) view.addSubview(hostingController.view) hostingController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ hostingController.view.topAnchor.constraint(equalTo: view.topAnchor), hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) hostingController.didMove(toParent: self) } } And then in UIKit source view: let viewController = ModalBugViewController() viewController.modalPresentationStyle = .overFullScreen present(viewController, animated: true) The bug is reproducible on iOS 18 - 26.1, even on the simulator, although on iOS 26 it's in landscape mode only. Is there some workaround for this issue that doesn't involve rewriting the whole dialog in UIKit?
1
0
38
6h
CRASH: in _SFAutomaticPasswordInputViewController on iOS 26.2 Beta 1 (23C5027f)
The application crashes immediately when the system attempts to display the automatic password input view controller (_SFAutomaticPasswordInputViewController). This occurs during the login or password-filling process. OS Version: iOS 26.2 Beta 1 Build Number: (23C5027f) Fatal Exception: NSInvalidArgumentException *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
2
1
50
7h
Delay timing to evaluate Menu content until it actually opens (macOS)
SwiftUI’s Menu is used also to display view controls like pop-up buttons. However, in such cases, its content is evaluated at the moment the button itself appears, although it’s not required until the menu is actually opened. Additionally, since the menu content isn’t re-evaluated when opened, if the content is dynamically generated, there could be a discrepancy between the actual state and the displayed state depending on the timing. Considering these points, I’d like to delay generating the menu content until the moment it’s actually opened. Is there a way to delay the evaluation and generation of the Menu’s content until the moment its contents are displayed? Note: I'd like to know about using it within a macOS app.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
1
0
115
7h
Sheet background in share extension ignores Liquid Glass effect in iOS 26/Xcode 26
I’m developing a share extension for iOS 26 with Xcode 26. When the extension’s sheet appears, it always shows a full white background, even though iOS 26 introduces a new “Liquid Glass” effect for partial sheets. Expected: The sheet background should use the iOS 26 glassmorphism effect as seen in full apps. Actual behavior: Custom sheets in my app get the glass effect, but the native system sheet in the share extension always opens as plain white. Steps to reproduce: Create a share extension using UIKit Present any UIViewController as the main view Set modalPresentationStyle = .pageSheet (or leave as default) Observe solid white background, not glassmorphism Sample code: swift override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .clear preferredContentSize = CGSize(width: UIScreen.main.bounds.width, height: 300) } Troubleshooting attempted: Tried adding UIVisualEffectView with system blur/materials Removed all custom backgrounds Set modalPresentationStyle explicitly Questions: Is it possible to enable or force the Liquid Glass effect in share extensions on iOS 26? Is this a limitation by design or a potential bug? Any workaround to make extension sheet backgrounds match system glass appearance?
4
0
112
8h
UITabBarController crashes when editing the items
I'm using one UITabBarController which leads to 6 NavigationController. Therefore the user will get 4 icons displayed and one icon with three points to see the rest of the Navigation Controller. If the user now tries to edit the list and moves one item from the hidden area towards the TabBar at the bottom, the App crashes with the error: Exception NSException * "Can't add self as subview" 0x0000600000d16040 I can see this effect at least on both my apps. If the same compilation is run on a older iOS version, there is no crash. Is there anything I have to take care of the configuration of the TabBar, when it comes to iOS26?
Topic: UI Frameworks SubTopic: UIKit
11
1
385
8h
VNDocumentCameraViewController UI issues in iOS 26
We're observing several UI issues with VNDocumentCameraViewController on devices running iOS 26. These screens were functioning correctly in earlier iOS versions. Issue 1 - On the edge correction screen, the top bar now appears as a gray strip beneath the status bar, whereas in previous iOS versions, it was positioned at the bottom of the screen. Do we have any workarounds to address this issue? Issue2 - The edit buttons and their labels are not clearly visible, affecting usability. Im using XCode 16.4 to build to iOS26 and the usage is like below: `let scanner = VNDocumentCameraViewController() scanner.delegate = self self.present(scanner, animated: true)`
2
1
131
8h
watchos 26
In the latest version of Watchos 26, an issue has been discovered with the following symptoms: Placing a button on an overlay page, buttonStyle(PlainButtonStyle()), Long press and slide, the button can actually slide and return to its original position. Previously, watchos did not have this problem. Can experts take a look
Topic: UI Frameworks SubTopic: SwiftUI
0
0
14
8h
Bar button item showing wrong overlay after pop transition on iOS 26.1
I am experiencing a frustrating bug on iOS 26.1 that makes my app look as if it lacks attention to detail. Basically, when having a NavigationStack, where the root view has a top-right confirmation bar button item, and a pushed detail view does not have any button in the navigation bar trailing position, upon poping back to the root view, the confirmation bar button item shows a white overlay for about 1-2 seconds before finally disappearing and showing the correct appearance. Here is the incorrect appearance right after the pop transition: Eventually after about 1,5 seconds it gets turned back to what it should look like: Here is the full code that you can use to reliably reproduce this issue on iOS 26.1: @State private var path: [Int] = [] var body: some View { NavigationStack(path: $path) { VStack { Text("First View") .font(.title) } .navigationDestination(for: Int.self, destination: { param in Text("Detail View") .font(.title) }) .navigationTitle("First") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItemGroup(placement: .confirmationAction) { Button("Next", role: .confirm, action: { self.path.append(1) }) } } } } } I submitted a Feedback for it: FB21010613 . Is there anything at all I can do on my end to work around this issue?
0
0
28
10h
iOS Dark mode Liquid Glass Tab bar with Reduce Transparency Issue
Hi, I have an iOS app that I’m trying to update with Liquid Glass. In this app, I’m using a tab bar, which works fine with Liquid Glass, but as soon as I enable the “Reduce Transparency” setting in dark mode, I get a strange effect: at launch, the tab bar appears correctly in dark mode, but after scrolling a bit in the view, it eventually switches to light mode 😅 At launch: After a bit of scrolling: I can’t figure out whether this is intended behavior from the framework or not (I don’t have this issue with other apps). I can reproduce it in a project built from scratch, here is the code (don't forget to set dark mode to the device and activate the reduce transparency option in the accessibility menu): struct ContentView: View { var body: some View { TabView { ScrollView { LazyVStack { ForEach(0..<100) { _ in Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello world").foregroundStyle(.primary) } } .padding() } .tabItem { Label("Menu", systemImage: "list.dash") } } } } Do you know if this is expected behavior? Or if there’s something that can be done about it? Thanks,
0
0
40
11h
SwiftUI navigationTransition Regression on iOS 26 (Source View Disappears + Flicker/Misaligned Geometry)
Summary I’m experiencing two issues with SwiftUI’s navigationTransition(.zoom) on iOS 26.0 and 26.1 that break previously smooth transitions. These issues appear both on real devices and Simulator. The same code works correctly on iOS 18. Issue 1 - Source View Disappears After Drag-Dismiss When using .navigationTransition(.zoom(sourceID:..., in:...)), the source view disappears completely after the transition finishes. This only happens when the detail view is dismissed via drag (interactive dismiss). When the view is dismissed by tapping the back button, the source view remains visible as expected. Reproduced on: iOS 26.0, iOS 26.0.1 (17A400), iOS 26.1 (Simulator + physical device) Issue 2 — Flickering and Geometry Mismatch During Transition Compared to iOS 18 behavior, the outgoing view and incoming view no longer share consistent geometry. Current behavior on iOS 26: The disappearing view flickers during the drag-dismiss interaction. The source and destination views no longer align geometrically. Instead of smoothly morphing as in previous iOS versions, the two views briefly overlap incorrectly before applying the zoom animation. Expected (iOS 18) behavior: Matched geometry between source and destination. Smooth, stable zoom transition with no flickering. // // ContentView.swift // DummyTransition // // Created by Sasha Morozov on 12/11/25. // import SwiftUI struct RectItem: Identifiable, Hashable { let id: UUID = UUID() let title: String let color: Color } struct ContentView: View { @Namespace private var zoomNamespace private let items: [RectItem] = [ RectItem(title: "Red card", color: .red), RectItem(title: "Blue card", color: .blue), RectItem(title: "Green card", color: .green), RectItem(title: "Orange card", color: .orange) ] var body: some View { NavigationStack { ScrollView { VStack(spacing: 16) { ForEach(items) { item in NavigationLink { DetailView(item: item, namespace: zoomNamespace) .navigationTransition( .zoom(sourceID: item.id, in: zoomNamespace) ) } label: { RoundedRectangle(cornerRadius: 16) .fill(item.color.gradient) .frame(height: 120) .overlay( Text(item.title) .font(.headline) .foregroundStyle(.white) ) .padding(.horizontal, 16) .matchedTransitionSource(id: item.id, in: zoomNamespace) } .buttonStyle(.plain) } } .padding(.vertical, 20) } .navigationTitle("Cards") } } } struct DetailView: View { let item: RectItem let namespace: Namespace.ID var body: some View { ZStack { item.color Text(item.title) .font(.largeTitle.bold()) .foregroundStyle(.white) } .ignoresSafeArea() .navigationTitle("Detail") .navigationBarTitleDisplayMode(.inline) } } #Preview { ContentView() } Testing Environment MacBook Pro (2023, M2 Pro, 16 GB RAM) macOS 26.2 Beta (25C5031i) Xcode: Version 26.0.1 (17A400) Devices tested: Simulator (iOS 26.0 / 26.1) Physical device (iPhone 16) running iOS 26.1
Topic: UI Frameworks SubTopic: SwiftUI
0
0
50
15h