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

Posts under SwiftUI tag

200 Posts

Post

Replies

Boosts

Views

Activity

"Searchable with .toolbarPrincipal incorrectly places search field at bottom instead of navigation bar"
When using .searchable with placement: .toolbarPrincipal inside a NavigationStack, the search field is incorrectly placed at the bottom of the view instead of the principal position where ToolbarPlacement.principal normally resides. This is confirmed by testing: a ToolbarItem with placement: .principal containing Text("Title") gets pushed away when the .searchable modifier is added, yet the search field still appears at the bottom rather than taking over the principal location as documented.
0
0
10
11h
Importing Data into SwiftData in the Background Using ModelActor and @Query
I have an app with fairly typical requirements - I need to insert some data (in my case from the network but could be anything) and I want to do it in the background to keep the UI responsive. I'm using SwiftData. I've created a ModelActor that does the importing and using the debugger I can confirm that the data is indeed being inserted. On the UI side, I'm using @Query and a SwiftUI List to display the data but what I am seeing is that @Query is not updating as the data is being inserted. I have to quit and re-launch the app in order for the data to appear, almost like the context running the UI isn't communicating with the context in the ModelActor. I've included a barebones sample project. To reproduce the issue, tap the 'Background Insert' button. You'll see logs that show items being inserted but the UI is not showing any data. I've tested on the just released iOS 18b3 seed (22A5307f). The sample project is here: https://hanchor.s3.amazonaws.com/misc/SwiftDataBackgroundV2.zip
24
13
6.1k
15h
fullScreenCover & Sheet modifier lifecycles
Hello everyone, I’m running into an issue where a partial sheet repeatedly presents and dismisses in a loop. Setup The main screen is presented using fullScreenCover From that screen, a button triggers a standard partial-height sheet The sheet is presented using .sheet(item:) Expected Behavior Tapping the button should present the sheet once and allow it to be dismissed normally. Actual Behavior After the sheet is triggered, it continuously presents and dismisses. What I’ve Verified The bound item is not being reassigned in either the parent or the presented view There is no .task, .onAppear, or .onChange that sets the item again The loop appears to happen without any explicit state updates Additional Context I encountered a very similar issue when iOS 26.0 was first released At that time, moving the .sheet modifier to a higher parent level resolved the issue The problem has now returned on iOS 26.4 beta I’m currently unable to reproduce this in a minimal sample project, which makes it unclear whether: this is a framework regression, or I’m missing a new presentation requirement Environment iOS: 26.4 beta Xcode: 26.4 beta I’ve attached a screen recording of the behavior. Has anyone else experienced this with a fullScreenCover → sheet flow on iOS 26.4? Any guidance or confirmation would be greatly appreciated. Thank you!
0
0
28
21h
What is the state of EventKit going forward?
I'm building an app that heavily relies on EKEventStore for calendar and reminder integration. The API is simple - and limited. Change notifications amount to "something changed, you'd better refetch everything you care about." There's no way to know whether the calendar was updated while your app was closed or backgrounded. EKEvents and EKReminders don't trigger SwiftUI view updates, so you end up shunting them into your own observable state and keeping the two in sync. My app is fairly complex rendering-wise, and I lament being locked into treating EKEventStore as a first-class citizen of my view and data layer. It makes everything clunkier, essentially shuts the door on modern features like undo/redo, and makes integrating with other calendar providers that much harder. I'm exploring a custom SwiftData DataStore ↔ EKEventStore sync engine, but this is no easy task. There are still many unknowns I'd need to spike out before I can even attempt a proper implementation. Still, I'm curious - is this something being actively worked on behind the scenes? Will we see a more modern, observable, SwiftUI-native EventKit integration in the future?
1
0
38
23h
Liquid Glass Button animating when behind a view when `.interactive()` modifier is applied
When using the .glassEffect modifier on a button in swiftui combined with the .interactive() modifier, the button continues to show the interactive animation even when it’s covered by another element. Example: ZStack { Button { print("Button overlayed by ZStack") // Does not trigger, but interactive animation still plays } label: { image } .glassEffect(.regular.interactive()) Rectangle().fill(.black.opacity(0.7)) } This occurs with overlays, ZStacks, and even if the overlay is a button. Example below: EDIT: It seems like rocketsim's gif recording doesnt show the bug for some reason... really strange... Edit 2: reuploaded gif, recorded as mp4 and converted to gif seems to have worked... Feedback ID: FB22054300 I've attached this sample app to my feedback ticket to help with debugging the issue. It doesn't look like I can share it in this post though.
1
1
38
2d
ProgressView in LiveActivities: missing functionality
Good afternoon all, I have a question about Live Activities, specifically ProgressView. Why are they so hard to customize? You can't even really, consistently make the bar a specific height in points. You can't provide any progress view style to make it richer and more dynamic. We want to build a progress bar that's built up of 3 components: a track with its value constant on 1.0 (the full progress) with a specific color, another track that's the actual progress from ProgressView(timerInterval:countsDown:), and some way to create a visual gap in between. The progress bar should also be bigger than the standard size from iOS, but that's also not possible. The corners become really ugly when you use the scaleEffect modifier. Please, if anyone has any ideas about customizing the ProgressView without me having to send push notifications to manually make sure the bar updates, comment down below.
0
0
29
2d
"NavigationLink in List incorrectly highlights when destination value exists in NavigationStack path"
In SwiftUI, when using NavigationStack with a path binding containing multiple instances of the same (or many with navigationPath()) model type (since model type are class type, this issue might occur on instances of class type too), any NavigationLink in a detail view that leads to a value already present anywhere in the navigation stack (which is in the path binding) will appear incorrectly highlighted upon the view's initial appearance. This bug seems manifests specifically when the links are contained within a List. The highlighting is inconsistent - only the earliest appended value in path has link in each section displays as pressed, while links to other value appear normal. Below is a simple code to reproduce the bug. import SwiftUI import SwiftData // Simple model @available(iOS 17, *) @Model class Item { var id = UUID() var name: String var relatedItems: [Item] init(name: String = "", relatedItems: [Item] = []) { self.name = name self.relatedItems = relatedItems } } // MARK: - Bug Reproducer @available(iOS 17, *) struct BugReproducerView: View { @State private var path: [Item] = [] let items: [Item] init() { let item1 = Item(name: "Item 1", relatedItems: []) let item2 = Item(name: "Item 2", relatedItems: [item1]) item1.relatedItems = [item2] self.items = [item1, item2] } var body: some View { NavigationStack(path: $path) { List(items) { item in NavigationLink(item.name, value: item) } .navigationTitle("Items") .navigationDestination(for: Item.self) { item in DetailView(item: item) } } } } // MARK: - Detail View with Bug @available(iOS 17, *) struct DetailView: View { let item: Item var body: some View { List { Section("Info") { Text("Selected: \(item.name)") } if !item.relatedItems.isEmpty { Section("Related") { ForEach(item.relatedItems) { related in NavigationLink(related.name, value: related) } } } } .navigationTitle(item.name) } } #Preview { if #available(iOS 17, *) { BugReproducerView() } else { } }
0
0
24
2d
TimelineView using ExplicitTimelineSchedule ignores last date?
Hi, everyone. I'm trying my first TimelineView with an explicit schedule, but my attempt – and even the simple example from the documentation – doesn't seem to work as documented. Here's what the documentation says an explicit schedule does: The timeline view updates its content on exactly the dates that you specify, until it runs out of dates, after which it stops changing. And it gives this example: let dates = [ Date(timeIntervalSinceNow: 10), // Update ten seconds from now, Date(timeIntervalSinceNow: 12), // and a few seconds later. ] struct MyView: View { var body: some View { TimelineView(.explicit(dates)) { context in Text(context.date.description) } } } There are stipulations about what the view – which always displays some version of its content body – will do given only past or future dates, but it seems clear we should expect the view in this example to redraw at least once after it appears. Here's the rest of the discussion from the documentation with my comments after testing what's stated: If the dates you provide are in the past, the timeline view updates exactly once with the last entry. That seems true, considering the "update" to be the initial draw. If you only provide dates in the future, the timeline view renders with the current date until the first date arrives. Not exactly: it looks the "date" property of the initial render is the (future) date of the first schedule entry, even though it's drawn early. When the first date does arrive, the body closure doesn't seem to be called. Only on the next date, if there is one, is it called again. If you provide one or more dates in the past and one or more in the future, the view renders the most recent past date, refreshing normally on all subsequent dates. That also seems correct, except… … that in every scenario, the final date entry seems to be ignored completely! In other words, unless all date entries are in the past, the Timeline View stops before it runs out of dates. That documented example from the start, which we expect to redraw at least once after it appears? When I test it in a Playground, it appears, but doesn't redraw at all! So, that's my main point of confusion after experimenting with TimelineView for the first time. I can achieve my own goal by appending an extra entry to my explicit schedule – even appending an entry identical to the previous "final" entry seems to work – but naturally that leaves me unclear about why I need to. If anyone can tell me what I'm not understanding, I'd be grateful.
4
2
821
3d
TabView with .page style vibrates and reloads content during sheet detent drag
FeedBack Id: FB22031397 (Demo proj Attached to Feedback) Description: When a TabView using .page tabViewStyle is placed inside a sheet configured with multiple presentationDetents, dragging the sheet handle to resize between detents causes the TabView to re-render all its pages on every frame of the drag gesture. This results in visible content vibration, scroll position jumping, and tab content flashing during the drag. The issue is fully reproducible with the attached minimal demo project. Steps to Reproduce: Run the attached TabViewSheetVibrationDemo.swift on any iOS device or simulator Tap "Open Sheet" on the main screen Swipe left to any tab Scroll down inside the tab so content is not at the top Grab the sheet drag indicator at the top and slowly drag upward or downward to resize between medium and large detent Observe the tab content while dragging Expected Results: The TabView page content should remain completely stable during sheet resize. Scroll positions should be preserved and no re-rendering should occur because the underlying data has not changed. The sheet should resize smoothly while tab content stays still. Actual Results: The TabView re-renders all pages on every frame of the drag gesture. This causes: Visible content vibration and jitter while dragging the sheet handle Scroll position jumping back toward the top mid-drag Tab content flashing as pages are recreated The problem is proportional to drag speed — slower drags show a stuttering effect, faster drags cause a full content flash Configuration: All Xcode including beta iOS 26 (also reproduced on iOS 16, iOS 17 and iOS 18) Reproducible on both Simulator and real device Affects iPhone and iPad
0
0
28
3d
Rendering Multi-Page PDF with SwiftUI View
I have the following code that renders a one-page PDF: func render() -> URL { let renderer = ImageRenderer(content: pdfView()) let url = URL.documentsDirectory.appending(path: "filename.pdf") renderer.render { size, context in var document = CGRect(x: 0, y: 0, width: 2550, height: 3300) guard let pdf = CGContext(url as CFURL, mediaBox: &document, nil) else { return } pdf.beginPDFPage(nil) context(pdf) pdf.endPDFPage() pdf.closePDF() } return url } func pdfView() -> some View { Text("View") } How can this be modified so that it renders a PDF with more than one page?
2
0
560
3d
Transparency in Sheet differs in SwiftUI and UIKit+UIHostingContrller
My app is a UIKit app with a lot of SwiftUI mixed in. A common scenario is that a UIViewController presents a sheet with a SwiftUI view wrapped in a UIHostingController. When I present the exact same SwiftUI View it looks different in a SwiftUI sheet compared to when it's wrapped in a UIHostingController and presented from a view controller. I'm using a hacky workaround in which I loop through all subviews of the hosting controller in viewWillLayoutSubviews and look for a NavigationStackHostingController<SwiftUI.AnyView> to manually set the background color, but it feels like it could brake easily. Has anyone found a better way to fix this? Feedback: FB22028838
0
1
51
4d
RealityView attachment draw order
My visionOS 26.3 app displays a diorama-like scene in a RealityView in a mixed immersive space, about 1 meter square, with view attachments floating above the scene. Each view attachment fades out after user interaction, by animating the view's opacity. What I'm observing is that depending on the position of a view attachment relative to the scene and the camera, an unwanted cutout effect is observed (presumably because of draw order issues), as shown in the right column in the screenshots below. YouTube video link of these sequences: https://youtu.be/oTuo0okKCkc (19 seconds) My question: How does visionOS determine the view attachment draw order relative to the RealityView scene? If I better understood how the draw order is determined, I could modify my scene to ensure that the view attachments were always drawn after the scene, fixing the unwanted cutout effect. I've successfully used ModelSortGroupComponent to control the draw order of entities within the RealityView scene, but my understanding is that this approach cannot be used with view attachments. I've submitted FB22014370 about this issue. Thank you.
0
0
96
6d
Does anyone know how to prevent Liqud Glass from stretching when elements with the glassEffect are dragged?
When making an element with .glassEffect(.clear.interactive()) draggable, it stretches as it moves. It seems like it's meant to stretch as you move your finger away from the element, but it doesn't make sense if the element is following your finger as you drag it. Is this a bug, or is there a way to disable this behavior without removing the other "interactive" animations? P.S. The shiny border around the elements seems to be a rounded rectangle or capsule, but the actual element's shape seems to be stretched. That also appears to be a bug.
0
0
54
6d
.navigationDestination(isPresented hangs after reboot in watchOS when destination view contains @Environment(\.dismiss)
.navigationDestination(isPresented) hangs after reboot (when called within 2 minutes of reboot) in watchOS when destination view contains @Environment(.dismiss). Feedback: FB21077151 Second button hangs after reboot. Hangs in watchOS 26.0 and 26.4 on a physical device. struct ContentView: View { @State var presentView1 : Bool = false @State var presentView2 : Bool = false var body: some View { NavigationStack { VStack { Button("Show View 1") { presentView1.toggle() } Button("Show View 2") { presentView2.toggle() } } .navigationDestination(isPresented: $presentView1, destination: {TestView1()}) .navigationDestination(isPresented: $presentView2, destination: {TestView2()}) } } } struct TestView1: View { var body: some View { Text("View 1") } } struct TestView2: View { @Environment(\.dismiss) var dismiss var body: some View { Text("View 2") } }
2
0
80
1w
Does Liquid Glass ignore regular hit testing in SwiftUI?
I’ve encountered an aspect of the Liquid Glass effect in SwiftUI that seems a bit odd: the Liquid Glass interaction appears to ignore regular hit-testing behavior. The following sample shows a button with hit testing disabled: @main struct LiquidGlassHitTestDemo: App { var body: some Scene { WindowGroup { Button("Liquid") { fatalError("Never called.") } .buttonStyle(.glassProminent) .allowsHitTesting(false) } } } As expected, the button’s action is never called. However, the interactive glass effect still responds to touch events: What’s even more surprising is that the UIKit equivalent behaves differently: final class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let button = UIButton( configuration: .prominentGlass(), primaryAction: UIAction( title: "Liquid", handler: { action in print("Never called.") } ) ) view.addSubview(button) button.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ button.centerXAnchor.constraint(equalTo: view.centerXAnchor), button.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) button.isUserInteractionEnabled = false } } In this case, the effect is not interactive at all. Similarly, if a UIViewController’s root view overrides hitTest(_:with:) to always return nil, the Liquid Glass effect does not react to touch events whatsoever. The only way I’ve found to “properly” disable the glass interactivity in SwiftUI is to use the .disabled(true) modifier. However, this also changes the button’s appearance, which is not always desirable. Is this expected behavior, or could this be a bug? Am I missing something about how Liquid Glass interaction is implemented in SwiftUI?
0
2
57
1w
Viewbased stereoscopic drawing
Is there a way to render stereoscopic (left/right) images in a 2d plane that resides in a swiftUI view? I know this is possible in realityKit shaders, and in immersive metal composits, but is it possible via swiftUI shaders, CAMetalLayer, etc? I'd like to draw a 2d window with standard UI chrome (resize, move etc) that displays stereoscopic content on the flat plane of the window.
1
0
614
1w
Support for trailing accessory views in Tab (sidebarAdaptable TabView)
In iOS 18, TabView with .tabViewStyle(.sidebarAdaptable) introduced a powerful adaptive pattern — tabs in compact, sidebar in regular. However, the current Tab API only supports a title and an image (icon). There is no way to provide a trailing accessory view (e.g., a secondary icon or indicator) for sidebar rows. This is a meaningful gap in the API, because trailing accessories are a well-established pattern throughout UIKit and SwiftUI. Precedent in Apple's own design language Apple already supports trailing accessories in many analogous contexts: UITableViewCell / UICollectionViewListCell — support accessories (disclosure indicators, checkmarks, custom views) via UICellAccessory. UIListContentConfiguration — allows leading and trailing content in list rows. SwiftUI List rows — support Label, HStack with trailing elements, .badge(), and swipeActions. NavigationLink — automatically renders a disclosure chevron as a trailing accessory. UITabSidebarItem (UIKit, iOS 18) — supports configurationUpdateHandler and cell accessories at the UIKit level. The sidebar of a .sidebarAdaptable TabView is visually identical to a List — yet its rows lack the accessory support that List rows have had for years. Real-world example: Photos app Apple's own Photos app (iPadOS 18+) demonstrates this exact need. In its sidebar, the "Recently Deleted" row displays a trailing lock icon to indicate that authentication is required to view the album. This is a meaningful UX element — it communicates state at a glance, without requiring the user to tap into the item. Third-party developers building with TabView(.sidebarAdaptable) have no public API to replicate this pattern. The Tab view builder's label closure is decomposed into a discrete title and image; any additional views (including Spacer() and trailing Image views within an HStack) are silently discarded by the system. What we've tried Custom label closure with HStack — trailing views are ignored. The system extracts only the first Image and Text. .badge() modifier — only supports Int or Text, not custom views such as icons. Label with complex content — the system normalizes it to icon + title. The only viable path today is to bridge to UIKit's UITabBarController and customize UITabSidebarItem directly, which defeats the purpose of using SwiftUI's declarative TabView API. Proposed API A trailing accessory modifier on Tab, consistent with existing SwiftUI patterns: Tab("Recently Deleted", systemImage: "trash", value: "deleted") { RecentlyDeletedView() } .tabSidebarAccessory { Image(systemName: "lock.fill") .foregroundStyle(.secondary) } // Option B: Text accessory (e.g., counts, status labels) Tab("Inbox", systemImage: "tray", value: "inbox") { InboxView() } .tabSidebarAccessory { Text("12") .font(.subheadline) .foregroundStyle(.secondary) } // Option C: Combined text + image accessory Tab("Shared Albums", systemImage: "rectangle.stack", value: "shared") { SharedAlbumsView() } .tabSidebarAccessory { HStack(spacing: 4) { Text("3 new") .font(.caption) .foregroundStyle(.secondary) Image(systemName: "person.2.fill") .foregroundStyle(.blue) } } Environment Platform: iPadOS / macOS Catalyst iOS version: 18.0+ Xcode: 16.0+ Component: SwiftUI TabView with .tabViewStyle(.sidebarAdaptable) Summary The Tab API should support trailing accessory content for sidebar rows, bringing it in line with the accessory support already available in UITableViewCell, UICollectionViewListCell, UIListContentConfiguration, and SwiftUI List. Apple's own Photos app demonstrates the need for this capability, yet no public API exists for third-party developers to achieve it.
2
0
78
1w
sharedBackgroundVisibility Not Removing Spacing
Any logical reason why applying .sharedBackgroundVisibility(.hidden) to a ToolbarItem would not remove the spacing allocated for glass border? Thus causing any element utilizing this functionality to appear offset from the regular buttons. Or is this yet another magical Apple experience I am not blessed enough to understand.
4
0
115
1w
WidgetKit: WidgetCenter.reloadAllTimelines() / reloadTimelines(ofKind:) requests are silently ignored/deferred, causing widget to remain unupdated UI Frameworks SwiftUI
Problem After launching the host app by tapping the widget (widgetURL), calls to: WidgetCenter.shared.reloadAllTimelines() WidgetCenter.shared.reloadTimelines(ofKind: ...) are ignored/deferred for an initial period right after the app opens. During this window, the widget does not reload its timeline and remains unupdated, no matter how many times I call the reload methods. After some time passes (typically ~30 seconds, sometimes shorter/longer), reload calls start working again. There is also no developer-visible signal (no callback/error/acknowledgement) that the reload was ignored, so the app can’t detect the failure and can’t reliably recover the flow. Question: Is this expected behavior (throttling/cooldown) after opening the app from a widget ? If so, is there any recommended workaround to update the widget reliably and quickly (or at least detect that the reload was not accepted)? Any guidance would help.
0
0
66
1w