Hi all, I’m running into a “double update” effect in SwiftUI when using the @Observable with @State. I’m trying to understand whether this is expected behavior, a misuse on my side, or a potential bug. Setup I have an observable store using the Observation macro: @Observable class AlbumStore { var albums: [Album] = [ Album(id: 1, title: Album 1, author: user1), Album(id: 2, title: Album 2, author: user1), Album(id: 3, title: Album 3, author: user1), Album(id: 4, title: Album 4, author: user1), Album(id: 5, title: Album 5, author: user1), Album(id: 6, title: Album 6, author: user1) ] func addAlbum(_ album: Album) { albums.insert(album, at: 0) } func removeAlbum(_ album: Album) { albums.removeAll(where: { $0 == album }) } } In my view, I inject it via @Environment and also keep some local state: @Environment(AlbumStore.self) var albumStore @State private var albumToAdd: Album? I derive a computed array that depends on both the environment store and local state: private var filteredAlbums: [Album] { let
Search results for
SwiftUI List performance
50,605 results found
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
This is a very interesting question, and you've done a great job of isolating the behavior and providing comparative examples. I’m not an expert on SwiftUI, wish I knew better, but that technology was always being really good at what you're seeing this double update with @Observable and @State, especially in conjunction with GeometryReader. When @Published properties change, they emit events. Views that are observing these properties (via @StateObject or @EnvironmentObject) then get scheduled for re-evaluation. The update cycle is generally more straightforward: state change -> event -> view re-render. filteredAlbums id: [3878E7A7-CDAB-444F-8B8C-263763735770, 1, 2, 3, 4, 5, 6] filteredAlbums id: [1, 2, 3, 4, 5, 6] You've triggered two state changes almost simultaneously: albumStore.addAlbum(newAlbum): This is a change to a property managed by your @Observable AlbumStore. albumToAdd = newAlbum: This is a change to a @State property within your view. Your carousel() function reads from albumStore
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags:
Oh, and I forgot to mention a couple of random caveats for the old hardware model technique I explained in the previous post: By bringing up a new OS on an old hardware model VM, you miss out on various features. Indeed, that’s kinda the point, in that you want to ‘miss out’ on the new-style provisioning UDIDs. However, there are other features, like using iCloud, that you might actually miss. And it’s not hard to imagine that list growing in the future. And speaking of the future, there’s no guarantee that this technique will work forever. I can imagine a world where a macOS NN guest simply won’t run on older hardware model VMs. Or that a old hardware model might stop being supported by the macOS host. You can detect the latter with isSupported, but the former is likely to result in either the OS failing to install or the OS not booting once it is installed. So, your default path should be to create your VM in the standard way, as illustrated by the Running macOS in a virtual machine on Apple silico
Topic:
App & System Services
SubTopic:
Core OS
Tags:
Thank you for your reply! I understand now, and was able to fix our code. I’d read the documentation page too quickly and misunderstood what it was saying exactly. It's pretty interesting that you need to read the environment not from within the row view, but from a descendant of it. For anyone else reading this, here’s some additional tests that helped me understand exactly the required setup. The third row especially (ListItemThinWrapper) seems to suggest you should be thinking in terms of resolved views, or something like that. struct ProminentBackgroundInList: View { var body: some View { List(selection: .constant(Set([0, 1, 2, 3]))) { ListItem().tag(0) // doesn't work ZStack { ListItem() // works }.tag(1) ListItemThinWrapper().tag(2) // doesn't work ListItemStackWrapper().tag(3) // works } } struct ListItem: View { @Environment(.backgroundProminence) var backgroundProminence var body: some View { HStack { Image(systemName: person.fill) .foregroundStyle(backgroundProminence == .standard ? .orange
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags:
When using an image in a List item, you sometimes want to tint that image, but only if the item isn’t selected. When it’s selected, you usually want the contents of the list item to be all-white, for contrast. The backgroundProminence Environment value ostensibly exists for this purpose, but in my tests, it never seems to change. Am I doing something wrong? Is there an alternative solution? For instance, this code: import SwiftUI struct ProminentBackgroundInList: View { var body: some View { List(selection: .constant(0)) { ListItem().tag(0) ListItem().tag(1) } } } struct ListItem: View { @Environment(.backgroundProminence) var backgroundProminence var body: some View { HStack { Image(systemName: person.fill) .foregroundStyle(backgroundProminence == .standard ? .orange : .primary) Text(Person) } } } #Preview { ProminentBackgroundInList() } Produces this result:
To more clearly state my question, what I’m really asking is: how does SwiftUI’s TextField work with Undo? What are the conditions to making that work?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I've spent a few months writing an app that uses SwiftData with inheritance. Everything worked well until I tried adding CloudKit support. To do so, I had to make all relationships optional, which exposed what appears to be a bug. Note that this isn't a CloudKit issue -- it happens even when CloudKit is disabled -- but it's due to the requirement for optional relationships. In the code below, I get the following error on the second call to modelContext.save() when the button is clicked: Could not cast value of type 'SwiftData.PersistentIdentifier' (0x1ef510b68) to 'SimplePersistenceIdentifierTest.Computer' (0x1025884e0). I was surprised to find zero hit when Googling Could not cast value of type 'SwiftData.PersistentIdentifier'. Some things to note: Calling teacher.computers?.append(computer) instead of computer.teacher = teacher results in the same error. It only happens when Teacher inherits Person. It only happens if modelContext.save() is called both times. It works if the first modelContext.save() is com
Hi Kevin, During the implementation of batch task buffer mapping, we observed an inconsistency between API return values and actual memory addresses, which leads to an immediate system Panic (Kernel Data Abort). Inside the implementation of UserMapBundledParallelTaskCommandAndResponseBuffers, we performed the following operations on the Response Buffer: We invoked CreateMapping(0, 0, 0, 0, 0, &ivars->fResponseMap) on the provided parallelResponseIOMemoryDescriptor. CreateMapping returns kIOReturnSuccess, and the resulting ivars->fResponseMap object pointer is non-null. However, a subsequent call to ivars->fResponseMap->GetAddress() returns NULL (0x0). After the DEXT returns from UserMapBundledParallelTaskCommandAndResponseBuffers with this NULL address, the system immediately triggers a Panic when the kernel attempts to process subsequent discovery commands (e.g., Inquiry). Panic Type: Kernel data abort Fault Address (FAR): 0x0000000000000000 Exception Class (ESR): 0x96000006 (Transla
Topic:
App & System Services
SubTopic:
Drivers
Tags:
Hi all - i'm encountering a strange issue since updating to Xcode 26.0.1. It seems that any SwiftUI Views that have an :ObservedObject property that contains @Published properties, and use those properties inside the View, no longer update when those properties are updated when the view also has an @Environment property. If I remove the @Environment property and any usage of it, the view updates correctly. The specific environment property i'm using is .safeAreaInsets, like so: @Environment(.safeAreaInsets) private var safeAreaInsets Is this a recognised bug in the latest iOS 26 SDK? Thanks
I'm running Xcode 26.2 (17C52). After deleting all simulators and creating new ones, SwiftUI Preview stopped working. Xcode reports: “Simulator [D774B214-XXXX-XXXX-XXXX-XXXXXXXX8288] failed to boot and may have crashed.” However, when I list all available simulators using xcrun simctl list, there is no simulator with that identifier. It seems Xcode is still referencing a previously deleted simulator. I have tried: Deleting all simulators again Creating new simulators Restarting Xcode and the system But the issue persists and Preview still fails to launch. Has anyone encountered this issue or knows how to clear the cached simulator reference used by SwiftUI Preview?
Hello, We are using a Message Filter Extension (ILMessageFilterExtension) to classify SMS/iMessage content (junk vs allow) in our app. After testing on iOS 26.1, we want to confirm whether there are any behavioral, performance, or API-level changes that impact message filtering, such as: Changes in how often the filter extension is invoked Differences in classification accuracy or system overrides New privacy, entitlement, or permission-related restrictions Execution time limits or memory constraints Any changes specific to iMessage vs SMS filtering We did not find any explicit mention of Message Filter Extensions in the iOS 26.1 release notes and would like to confirm whether the existing behavior from previous iOS versions remains unchanged. Has Apple introduced any known or undocumented changes in iOS 26.1 that developers should be aware of when supporting Message Filter Extensions? Sometime I also found unpredictable behaviour on iOS version 18.5 or below, like sometime it works but sometimes sta
Feedback ticket ID: FB21797397 Summary When using posix_spawn() with posix_spawnattr_set_uid_np() to spawn a child process with a different UID, the eslogger incorrectly reports a setuid event as an event originating from the parent process instead of the child process. Steps to Reproduce Create a binary that do the following: Configure posix_spawnattr_t that set the process UIDs to some other user ID (I'll use 501 in this example). Uses posix_spawn() to spawn a child process Run eslogger with the event types setuid, fork, exec Execute the binary as root process using sudo or from root owned shell Terminate the launched eslogger Observe the process field in the setuid event Expected behavior The eslogger will report events indicating a process launch and uid changes so the child process is set to 501. i.e.: fork setuid - Done by child process exec Actual behavior The process field in the setuid event is reported as the parent process (that called posix_spawn) - indicating UID change to the parent process. Att
Hello Cykelero, Thanks for your question. Please see the following section in the entry for backgroundProminence: Note that the use of backgroundProminence was used by a view that was nested in additional stack containers within the row. This ensured that the value correctly reflected the environment within the list row itself, as opposed to the environment of the list as a whole. One way to ensure correct resolution would be to prefer using this in a custom ShapeStyle instead, for example: and Views like List and Table as well as standard shape styles like ShapeStyle.selection will automatically update the background prominence of foreground views. By modifying your code to use a custom ShapeStyle, I was able to colorize the Image accordingly: struct ListItem: View { var body: some View { HStack { Image(systemName: person.fill) .foregroundStyle(FillStyle()) Text(Person) } } } extension ListItem { struct FillStyle: ShapeStyle { func resolve(in env: EnvironmentValues) -> some Shap
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags:
Thanks for the post, so when using the https://developer.apple.com/documentation/carplay/cpcontacttemplate api for CarPlay has changed the output from iOS 16 to 26? Can you provide a focused sample showing the issue? The most common reason for buttons not showing is incorrect setup. The code for creating and configuring the buttons must be correct. Are you correctly initializing the button classes (e.g., CPContactCallButton())?Are you setting the properties of the buttons correctly (e.g., contactName, phoneNumber, messageBody)?Ensure you have implemented logic to handle button presses. Buttons require interaction to perform actions. Without either the target-action pattern (using addTarget) or implementing a CPButton delegate method the buttons have nothing to execute. The template needs to be presented using the correct CarPlay CPInterfaceController. Ensure that you are displaying your CPContactTemplate through the CarPlay interface. Ensure the view controller which is housing the CarPlay template i
Thanks for the post. My apologies as is hard to follow the code as the .cueStyle() is in else? so the if #available(macOS 26.0, *) { won’t apply there as far as I can tell. Can you post the code in a better way? There is a way I personally handle conditional modifiers in SwiftUI without duplicating large blocks of code. You can use an extension to conditionally apply the appropriate modifier based on the macOS version, while ensuring both modifiers conform to the same type. One approach is to define a protocol that both GlassCueStyle and CueStyle conform to, and then use that protocol to write a conditional modifier. protocol CueStyleModifier: ViewModifier { init(font: Font) } Maybe too over complicating that? Make sure both GlassCueStyle and CueStyle conform to the protocol. Create a conditional extension on View to apply the correct modifier. extension View { func applyCueStyle(font: Font = .system(size: 45)) -> some View { #if os(macOS) && targetEnvironment(macCatalyst) if #available(ma
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: