I'm running into a weird SwiftUI concurrency issue that only seems to happen on a real device (iOS 18.5 in my case), and not in simulator. I have a NavigationSplitView where the Detail view uses .task(id:_:) to perform some async work upon appearance (in my real-world case, a map snapshot). When running this on a real device, the first execution of the task works as expected. However, any task subsequent executions, even ones for the same id, always start in the Task.isCancelled state.
Is there something about .task(id:_:) that I'm misunderstanding, or have I stumbled upon a serious bug here?
import SwiftUI
struct ContentView: View {
var body: some View {
TaskBugSplitView()
}
}
struct TestItem: Identifiable, Hashable {
var id: Int
var name: String
}
struct TaskBugSplitView: View {
@State
private var selectedItemIndex: [TestItem].Index?
@State
private var testItems: [TestItem] = [
TestItem(id: 1, name: "First Item"),
TestItem(id: 2, name: "Second Item"),
TestItem(id: 3, name: "Third Item"),
TestItem(id: 4, name: "Fourth Item"),
TestItem(id: 5, name: "Fifth Item")
]
var body: some View {
NavigationSplitView {
List(testItems.indices, id: \.self, selection: $selectedItemIndex) { item in
Text(testItems[item].name)
}
} detail: {
if let selectedItemIndex {
TaskBugDetailView(item: testItems[selectedItemIndex])
} else {
Text("Select an item")
.foregroundStyle(.secondary)
}
}
}
}
struct TaskBugDetailView: View {
@State var item: TestItem
@State private var taskResult = "Not started"
var body: some View {
VStack(spacing: 20) {
Text("Item: \(item.name)")
.font(.title2)
Text("Task Result:")
.font(.headline)
Text(taskResult)
.foregroundStyle(taskResult.contains("CANCELLED") ? .red : .primary)
Spacer()
}
.padding()
.navigationTitle(item.name)
.task(id: item.id) {
// BUG: On real devices, Task.isCancelled is true immediately for all tasks
// after the first successful one, even though the ID has changed
if Task.isCancelled {
taskResult = "CANCELLED at start"
print("Task cancelled at start for item \(item.id)")
return
}
taskResult = "SUCCESS"
print("Task completed successfully for item \(item.id)")
}
}
}
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Posts under SwiftUI tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
[Submitted as FB18870294, but posting here for visibility.]
In iOS 26 beta 3 (23A5287g), implicit animations no longer work when conditionally showing or hiding rows in a Form.
Rows with Text or other views inside a Section appear and disappear abruptly, even when wrapped in withAnimation or using .animation() modifiers. This is a regression from iOS 18.5, where the row item animates in and out correctly with the same code.
Repro Steps
Create a new iOS App › SwiftUI project.
Replace its ContentView struct with the code below
Build and run on an iOS 18 device.
Tap the Show Middle Row toggle and note how the Middle Row animates.
Build and run on an iOS 26 beta 3 device.
Tap the Show Middle Row toggle.
Expected
Middle Row item should smoothly animate in and out as it does on iOS 18.
Actual
Middle Row item appears and disappears abruptly, without any animation.
Code
struct ContentView: View {
@State private var showingMiddleRow = false
var body: some View {
Form {
Section {
Toggle(
"Show **Middle Row**",
isOn: $showingMiddleRow.animation()
)
if showingMiddleRow {
Text("Middle Row")
}
Text("Last Row")
}
}
}
}
TabView page control element has a bug on iOS 16 if tabview is configured as RTL with PageTabViewStyle.
Found iOS 16 Issues:
Page indicators display dots in reverse order (appears to treat layout as LTR while showing RTL)
Index selection is reversed - tapping indicators selects wrong pages
Using the page control directly to navigate eventually breaks the index binding
The underlying index counting logic conflicts with the visual presentation
iOS 18 Behavior:
Works as expected with correct dot order and index selection.
Xcode version:
Version 16.3 (16E140)
Conclusion:
Confirmed broken on iOS 16
Confirmed working on iOS 18
iOS 17 and earlier versions not yet tested
I've opened a feedback assistant ticket quite a while ago but there is no answer. There's a code example and a video there.
Anyone else had experience with this particular bug?
Here's the code:
public struct PagingView<Content: View>: View {
//MARK: - Public Properties
let pages: (Int) -> Content
let numberOfPages: Int
let pageMargin: CGFloat
@Binding var currentPage: Int
//MARK: - Object's Lifecycle
public init(currentPage: Binding<Int>,
pageMargin: CGFloat = 20,
numberOfPages: Int,
@ViewBuilder pages: @escaping (Int) -> Content) {
self.pages = pages
self.numberOfPages = numberOfPages
self.pageMargin = pageMargin
_currentPage = currentPage
}
//MARK: - View's Layout
public var body: some View {
TabView(selection: $currentPage) {
ForEach(0..<numberOfPages, id: \.self) { index in
pages(index)
.padding(.horizontal, pageMargin)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
.ignoresSafeArea()
}
}
//MARK: - Previews
struct ContentView: View {
@State var currentIndex: Int = 0
var body: some View {
ZStack {
Rectangle()
.frame(height: 300)
.foregroundStyle(Color.gray.opacity(0.2))
PagingView(
currentPage: $currentIndex.onChange({ index in
print("currentIndex: ", index)
}),
pageMargin: 20,
numberOfPages: 10) { index in
ZStack {
Rectangle()
.frame(width: 200, height: 200)
.foregroundStyle(Color.gray.opacity(0.2))
Text("\(index)")
.foregroundStyle(.brown)
.background(Color.yellow)
}
}.frame(height: 200)
}
}
}
#Preview("ContentView") {
ContentView()
}
extension Binding {
@MainActor
func onChange(_ handler: @escaping (Value) -> Void) -> Binding<Value> {
Binding(
get: { self.wrappedValue },
set: { newValue in
self.wrappedValue = newValue
handler(newValue)
}
)
}
}
The new drag & drop APIs for macOS 26 are terrific, but there's an important missing piece. If I use draggable(containerItemID:), there's no way to provide a custom view for the drag image. Meanwhile the older API lets you provide a preview, but you miss out on things like multi-item drag and custom drag sessions. Is there some mechanism for supplying a preview that I'm not seeing? Without it, the drag interface in my apps is going to look terrible.
How to Support Menu Bar Copy/Paste/Cut/Delete Commands on iPadOS with SwiftUI?
(Xcode 26 beta 4, iPadOS 26 beta 4)
We’re working on adding menu bar support to our SwiftUI app on iPadOS, aiming to provide a more consistent and productive experience across platforms.
However, we’ve encountered a challenge when trying to handle standard editing commands like Copy, Cut, Paste, and Delete from the menu bar:
On iPadOS, SwiftUI modifiers such as onCopyCommand, onCutCommand, onPasteCommand, and onDeleteCommand appear to be unavailable.
Additionally, since we can’t hide or override the default app menus, we’re unsure how to hook into or replace their behavior effectively.
Question:
What’s the recommended way to support standard editing actions like copy/paste via the menu bar in SwiftUI on iPadOS? Are there any workarounds or APIs we might have overlooked?
Any guidance or best practices would be greatly appreciated!
Feedback ID: FB18792279
Hi all.
I have tried using UIDesignRequiresCompatibility YES & NO for an application.
Running on iOS 26 BETA 5 makes no difference to the UI.
Running on Simulator MacOSS 26 BETA 5 makes no difference to the UI.
Anyone had luck with this info plist setting?
I am facing a recurring issue with Xcode iOS simulator. I want to preview a SwiftUI for iOS in Xcode, but the Simulator app fails to boot up.
I receive the follow error in Xcode:
Cannot Preview in this file. Simulator was shutdown during an update.
I have tried the following:
Deleting Xcode cache
Reinstalling iOS Simulator runtimes
Completely uninstalling Xcode and deleting all developer data, then reinstalling
None of the above steps fix the problem. The only fix I have found is to completely reinstall MacOS 15.4.1. THIS IS TERRIBLE!
I have already reinstalled MacOS 15.4.1 once to fix the issue, and I don't want to do it again. If there is another solution, please help me find it!
Thank you!!
I’m trying to use the new safeAreaBar() to place a button in the bottom safe area of the view for the main action. However, there’s a bug when the view is inside a NavigationStack: a white or translucent background appears around the button. When I move the view outside of the NavigationStack, the issue goes away.
NavigationStack {
List {
Text("ok")
}
.safeAreaBar(edge: .bottom) {
Button(action: {}, label: {
Text("Continue").font(.headline)
})
.buttonStyle(.glassProminent)
}
}
Is it a known issue?
I am confused about the "inheritance" behavior of modifiers in SwiftUI. Some modifiers (such as .background, .clipShape, etc.) seem to affect both parent and child views inconsistently. Here are some specific examples I encountered in Xcode 16.4 with the iOS 18.5 iPhone 16 Pro simulator:
struct ContentView: View {
var body: some View {
VStack { // RedVStack
Text("Hello world!")
VStack { // OrangeVStack
Text("Hello")
Text("Hello")
}
.background(.orange)
}
.background(.red, in: RoundedRectangle(cornerRadius: 5))
// RedVStack has rounded corners, OrangeVStack also has rounded corners
}
}
struct ContentView: View {
var body: some View {
VStack { // RedVStack
Text("Hello world!")
VStack { // OrangeVStack
Text("Hello")
Text("Hello")
}
.background(.orange)
Text("Hello world!")
}
.background(.red, in: RoundedRectangle(cornerRadius: 5))
// RedVStack has rounded corners, OrangeVStack does not have rounded corners
}
}
struct ContentView: View {
var body: some View {
VStack { // RedVStack
Text("Hello world!")
VStack { // OrangeVStack
Text("Hello")
Text("Hello")
}
.background(.orange)
}
.background(.red)
.clipShape(RoundedRectangle(cornerRadius: 5))
// RedVStack has rounded corners, OrangeVStack does not have rounded corners
}
}
I find it difficult to understand which modifiers affect child views and which do not. Is there any official documentation or authoritative explanation that can help me understand the scope and "inheritance" mechanism of SwiftUI modifiers? Thank you!
Platform: visionOS 2.6
Framework: RealityKit, SwiftUIComponent: ImagePresentationComponent
I’m working with the new ImagePresentationComponent from visionOS 26 and hitting a rendering limitation when switching to .spatialStereoImmersive viewing mode within a WindowGroup context.
This is what I’m seeing:
Pure immersive space: ImagePresentationComponent with .spatialStereoImmersive mode works perfectly in a standalone ImmersiveSpace
Mode switching API: All mode transitions work correctly (logs confirm the component updates)
Spatial content: .spatialStereo mode renders correctly in both window and immersive contexts.
This is where it’s breaking for me:
Window context: When the same RealityView + ImagePresentationComponent is placed inside a WindowGroup (even when that window is floating in a mixed immersive space), switching to .spatialStereoImmersive mode shows no visual change
The API calls succeed, state updates correctly, but the immersive content doesn’t render.
Apple’s Spatial Gallery demonstrates exactly what I’m trying to achieve:
Spatial photos displayed in a window with what feels like horizontal scroll view using system window control bar, etc.
Tapping a spatial photo smoothly transitions it to immersive mode in-place.
The immersive content appears to “grow” from the original window position by just changing IPC viewing modes.
This proves the functionality should be possible, but I can’t determine the correct configuration.
So, my question to is:
Is there a specific RealityView or WindowGroup configuration required to enable immersive content rendering from window contexts that you know of?
Are there bounds/clipping settings that need to be configured to allow immersive content to “break out” of window constraints?
Does .spatialStereoImmersive require a specific rendering context that’s not available in windowed RealityView instances?
How do you think Apple’s SG app achieves this functionality?
For a little more context:
All viewing modes are available: [.mono, .spatialStereo, .spatialStereoImmersive]
The spatial photos are valid and work correctly in pure immersive space
Mixed immersive space is active when testing window context
No errors or warnings in console beyond the successful mode switching logs I’m getting
Any insights into the proper configuration for window-hosted immersive content
Trying to implement my own forward/back buttons for the new SwiftUI WebView and reading the documentation I’m totally lost.
What’s the recommended way of implementing forward/back behavior with this component?
One of the bar button items of my bottom toolbar needs to be a custom view., and I’m trying hard to get it to behave like the proper bar button items when it comes to Liquid Glass and matching the appearance of all the other bar button items on my toolbar. I’ve tried many variations of embedding custom views within visual effect views, and this comes closest.
I inited a UIBarButtonItem with a custom UIView like you’re supposed to, and then I placed a UIVisualEffectView with Vibrancy within that, so that I could place a UIImageView inside it and the UIImageView would respect the adaptive color changing that comes with being within a Liquid Glass bar button item. I’ve made sure that the UIImageView is using an SF Symbol and a rendering mode of .alwaysTemplate, and that the .tintColor is set to .label, to ensure that I’m not overriding any Liquid Glass rendering.
Below, you can see the bar button item with my custom view on the left, and a native Bar Button Item with the same SF symbol on the right, in several scenarios. It gets part of the way there there: against light backgrounds the image view turns black like it should. But against darker backgrounds, instead of turning white, the symbol has an additional vibrancy that comes close to the right white look against certain grays, but then is obviously too translucent against black.
The symbol is still visible/experiencing some vibrancy, so I assume it might be some configuration of the UIImageView within the Vibrancy that can correct the behavior to match the images in the native bar button items in all conditions. Anyone got thoughts on what the missing piece might be?
Hi ,
I'm struggling with visionOS window management and need help with closing child windows programmatically.
App Structure
My app has a Main-Sub window hierarchy:
AWindow (Home/Main)
BWindow (Main feature window)
CWindow (Tool window - child of BWindow)
Navigation flow:
AWindow → BWindow (switch, 1 window on screen)
BWindow → CWindow (opens child, 2 windows on screen)
I want BWindow and CWindow to be separate movable windows (not sheet/popover) so users can position them independently in space.
The Problem
CWindow doesn't close when BWindow closes by tapping the X button below the app (next to the window bar)
User clicks X on BWindow → BWindow closes but CWindow remains
CWindow becomes orphaned on screen
Can close CWindow programmatically when switching BWindow back to AWindow
App launch issue
After closing both windows, CWindow is remembered as last window
Reopening app shows only CWindow instead of BWindow
User gets stuck in CWindow with no way back to BWindow
I've Tried Environment dismissWindow in cleanup but its not working.
// In BWindow.swift
.onDisappear {
if windowManager.isWindowOpen("cWindow") {
dismissWindow(id: "cWindow")
}
}
My App Structure Code Now
// in MyNameApp.swift
@main
struct MyNameApp: App {
var body: some Scene {
WindowGroup(id: "aWindow") {
AWindow()
}
WindowGroup(id: "bWindow") {
BWindow()
}
WindowGroup(id: "cWindow") {
CWindow()
}
}
}
// WindowStateManager.swift
class WindowStateManager: ObservableObject {
static let shared = WindowStateManager()
@Published private var openWindows: Set<String> = []
@Published private var windowDependencies: [String: String] = [:]
private init() {}
func markWindowAsOpen(_ id: String) {
markWindowAsOpen(id, parent: nil)
}
func markWindowAsClosed(_ id: String) {
openWindows.remove(id)
windowDependencies[id] = nil
}
func isWindowOpen(_ id: String) -> Bool {
let isOpen = openWindows.contains(id)
return isOpen
}
func markWindowAsOpen(_ id: String, parent: String? = nil) {
openWindows.insert(id)
if let parentId = parent {
windowDependencies[id] = parentId
}
}
func getParentWindow(of childId: String) -> String? {
let parent = windowDependencies[childId]
return parent
}
func getChildWindows(of parentId: String) -> [String] {
let children = windowDependencies.compactMap { key, value in
value == parentId ? key : nil
}
return children
}
func setNextWindowParent(_ parentId: String) {
UserDefaults.standard.set(parentId, forKey: "nextWindowParent")
}
func getAndClearNextWindowParent() -> String? {
let parent = UserDefaults.standard.string(forKey: "nextWindowParent")
UserDefaults.standard.removeObject(forKey: "nextWindowParent")
return parent
}
func forceCloseChildWindows(of parentId: String) {
let children = getChildWindows(of: parentId)
for child in children {
markWindowAsClosed(child)
NotificationCenter.default.post(
name: Notification.Name("ForceCloseWindow"),
object: nil,
userInfo: ["windowId": child]
)
forceCloseChildWindows(of: child)
}
}
func hasMainWindowOpen() -> Bool {
let mainWindows = ["main", "bWindow"]
return mainWindows.contains { isWindowOpen($0) }
}
func cleanupOrphanWindows() {
for (child, parent) in windowDependencies {
if isWindowOpen(child) && !isWindowOpen(parent) {
NotificationCenter.default.post(
name: Notification.Name("ForceCloseWindow"),
object: nil,
userInfo: ["windowId": child]
)
markWindowAsClosed(child)
}
}
}
}
// BWindow.swift
struct BWindow: View {
@Environment(\.dismissWindow) private var dismissWindow
@ObservedObject private var windowManager = WindowStateManager.shared
var body: some View {
VStack {
Button("Open C Window") {
windowManager.setNextWindowParent("bWindow")
openWindow(id: "cWindow")
}
}
.onAppear {
windowManager.markWindowAsOpen("bWindow")
}
.onDisappear {
windowManager.markWindowAsClosed("bWindow")
windowManager.forceCloseChildWindows(of: "bWindow")
}
.onChange(of: scenePhase) { oldValue, newValue in
if newValue == .background || newValue == .inactive {
windowManager.forceCloseChildWindows(of: "bWindow")
}
}
}
}
// CWindow.swift
import SwiftUI
struct cWindow: View {
@ObservedObject private var windowManager = WindowStateManager.shared
@State private var shouldClose = false
var body: some View {
// Content
}
.onDisappear {
windowManager.markWindowAsClosed("cWindow")
NotificationCenter.default.removeObserver(
self,
name: Notification.Name("ForceCloseWindow"),
object: nil
)
}
.onChange(of: scenePhase) { oldValue, newValue in
if newValue == .background {
}
}
.onAppear {
let parent = windowManager.getAndClearNextWindowParent()
windowManager.markWindowAsOpen("cWindow", parent: parent)
NotificationCenter.default.addObserver(
forName: Notification.Name("ForceCloseWindow"),
object: nil, queue: .main) { notification in
if let windowId = notification.userInfo?["windowId"] as? String, windowId == "cWindow" {
shouldClose = true
}
}
}
.onChange(of: shouldClose) { _, newValue in
if newValue {
dismissWindow()
}
}
}
The logs show everything executes correctly, but CWindow remains visible on screen.
Questions
Why doesn't dismissWindow(id:) work in cleanup scenarios?
Is there a proper way to create a window relationships like parent-child relationships in visionOS?
How can I ensure main windows open on app launch instead of tool windows?
What's the recommended pattern for dependent windows in visionOS?
Environment: Xcode 16.2, visionOS 2.0, SwiftUI
I'm working on the control widget which should display the SF image on the UI, but I have found that it cannot be displayed stably. I have eight CarCtrlWidgets which is about the type doorLock、chargeCover、frontBox、 locateCarLight、 locateCarHorn、 ventilate、 backBox and airCondition, it should all be showed but sometime they only show the text and placeholder. I'm aware of the images should be custom SF image and I can see them to show perfectly sometimes, but in other time it is just failed. This's really confused me, can anyone help me out?
deviceversion 18.5;device model iPhone 16 pro;
Hello Apple Developer Community: I have a problem with the fullscreencover. I can see the Things, that shouldn’t be visible behind it.
I’m currently developing with iOS 26 and only there it happens.
I hope you can help me :)
Have a nice day
I have an issue with Xcode that it crashes my Macbook and restarts it instantly when I unpause the preview canvas.
I managed to make it run for a minute longer by not watching a youtube video.
I am writing a very simple SwiftUI project for iOS nothing too big to warrant any issues.
Does anyone have a solution to fix this?
Macbook Pro M3 16GB RAM, 500GB SSD (plenty of storage space)
Tahoe 26.0
My sample app has been working with the following code:
func call(arguments: Arguments) async throws -> ToolOutput {
var temp:Int
switch arguments.city {
case .singapore: temp = Int.random(in: 30..<40)
case .china: temp = Int.random(in: 10..<30)
}
let content = GeneratedContent(temp)
let output = ToolOutput(content)
return output
}
However in 26 beta 5, ToolOutput no longer available, please advice what has changed.
I made a (very simple) custom tab bar in SwiftUI. It's simply an HStack containing two buttons. These buttons control the selection of a paged TabView. This works well, but in VoiceOver they don't behave like the bottom tab bar or e.g. a segmented picker. Specifically, VoiceOver does not say something like "tab one of two" when the first button is focused.
According to my research, in UIKit this can be accomplished by giving the container view the accessibility trait tabBar, hiding it as an accessibility element and give it the accessibility container type semanticGroup.
In SwiftUI, there is also the trait isTabBar, but that does not seem to have any impact for VoiceOver. I don't see an equivalent of semanticGroup in SwiftUI. I tried accessibilityElement(children: .contain) but that also does not seem to have any impact.
So, is there any way in SwiftUI to make a button behave like a tab-button in VoiceOver? And how is SwiftUI's isTabBar accessibility trait supposed to be used?
With Xcode 26.0 Beta 4 the container concentric API is finally available, which is great!
What I was wondering is how to use this API for button shapes. At the moment it seems that there is no ButtonBorderShape available that would behave like ConcentricRectangle.
Is this intentional or is it expected that with upcoming beta versions we can also use the concentric style as button border shapes? Or is there maybe another way of getting the buttons shape to behave like a concentric shape?
A use case I currently see is having the button as part of a container, using the .bordered button style and then aligning the corners of the button use the concentric style.
Any information about this is highly appreciated. Thank you very much!
I'm working with an app that has a structure of a main TabView, where each Tab has its own NavigationStack. A very simplified rendition of the app looks like this:
struct ContentView: View {
var body: some View {
TabView {
Tab("Tab 1", systemImage: "document") {
NavigationStack {
VStack {
Text("Tab 1")
NavigationLink("Load Detail") {
VStack {
Text("Detail View")
}.toolbarVisibility(.hidden, for: .bottomBar, .tabBar)
}
}
}
}
Tab("Tab 2", systemImage: "map") {
NavigationStack {
VStack {
Text("Tab 2")
}
}
}
}.tabViewBottomAccessory {
Button("Action") {}
}
}
}
With this structure, when I load the detail view in the NavigationLink, I see the tab bar hidden as I would expect. Unfortunately, the tabViewBottomAccessory button remains visible. I've taken some steps to try and fix this ( injecting state at different levels that observe the navigation path and try to change the visibility ) but none of those attempts work, and it seems to me that fundamentally, if the tab bar is desired to be hidden, then so also should the tab accessory be hidden.
I didn't find anywhere online that seemed to indicate this was a known bug, so wanted to post this here first to see if this was the behavior that is expected, or worth filing a bug in iOS 26.