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

Posts under SwiftUI tag

147 Posts

Post

Replies

Boosts

Views

Activity

SwiftData Many-To-Many Relationship: Failed to fulfill link PendingRelationshipLink
Hi there, I got two models here: Two Models, with Many-To-Many Relationship @Model final class PresetParams: Identifiable { @Attribute(.unique) var id: UUID = UUID() var positionX: Float = 0.0 var positionY: Float = 0.0 var positionZ: Float = 0.0 var volume: Float = 1.0 @Relationship(deleteRule: .nullify, inverse: \Preset.presetAudioParams) var preset = [Preset]() init(position: SIMD3<Float>, volume: Float) { self.positionX = position.x self.positionY = position.y self.positionZ = position.z self.volume = volume self.preset = [] } var position: SIMD3<Float> { get { return SIMD3<Float>(x: positionX, y: positionY, z: positionZ) } set { positionX = newValue.x positionY = newValue.y positionZ = newValue.z } } } @Model final class Preset: Identifiable { @Attribute(.unique) var id: UUID = UUID() var presetName: String var presetDesc: String? var presetAudioParams = [PresetParams]() // Many-To-Many Relationship. init(presetName: String, presetDesc: String? = nil) { self.presetName = presetName self.presetDesc = presetDesc self.presetAudioParams = [] } } To be honest, I don't fully understand how the @Relationship thing works properly in a Many-To-Many relationship situation. Some tutorials suggest that it's required on the "One" side of an One-To-Many Relationship, while the "Many" side doesn't need it. And then there is an ObservableObject called "ModelActors" to manage all ModelActors, ModelContainer, etc. ModelActors, ModelContainer... class ModelActors: ObservableObject { static let shared: ModelActors = ModelActors() let sharedModelContainer: ModelContainer private init() { var schema = Schema([ // ... Preset.self, PresetParams.self, // ... ]) do { sharedModelContainer = try ModelContainer(for: schema, migrationPlan: MigrationPlan.self) } catch { fatalError("Could not create ModelContainer: \(error.localizedDescription)") } } } And there is a migrationPlan: MigrationPlan // MARK: V102 // typealias ... // MARK: V101 typealias Preset = AppSchemaV101.Preset typealias PresetParams = AppSchemaV101.PresetParams // MARK: V100 // typealias ... enum MigrationPlan: SchemaMigrationPlan { static var schemas: [VersionedSchema.Type] { [ AppSchemaV100.self, AppSchemaV101.self, AppSchemaV102.self, ] } static var stages: [MigrationStage] { [AppMigrateV100toV101, AppMigrateV101toV102] } static let AppMigrateV100toV101 = MigrationStage.lightweight(fromVersion: AppSchemaV100.self, toVersion: AppSchemaV101.self) static let AppMigrateV101toV102 = MigrationStage.lightweight(fromVersion: AppSchemaV101.self, toVersion: AppSchemaV102.self) } // MARK: Here is the AppSchemaV101 enum AppSchemaV101: VersionedSchema { static var versionIdentifier: Schema.Version = Schema.Version(1, 0, 1) static var models: [any PersistentModel.Type] { return [ // ... Preset.self, PresetParams.self ] } } Fails on iOS 18.3.x: "Failed to fulfill link PendingRelationshipLink" So I expected the SwiftData subsystem to work correctly with version control. A good news is that on iOS 18.1 it does work. But it fails on iOS 18.3.x with a fatal Error: "SwiftData/SchemaCoreData.swift:581: Fatal error: Failed to fulfill link PendingRelationshipLink(relationshipDescription: (<NSRelationshipDescription: 0x30377fe80>), name preset, isOptional 0, isTransient 0, entity PresetParams, renamingIdentifier preset, validation predicates (), warnings (), versionHashModifier (null)userInfo {}, destination entity Preset, inverseRelationship (null), minCount 0, maxCount 0, isOrdered 0, deleteRule 1, destinationEntityName: "Preset", inverseRelationshipName: Optional("presetAudioParams")), couldn't find inverse relationship 'Preset.presetAudioParams' in model" Fails on iOS 17.5: Another Error I tested it on iOS 17.5 and found another issue: Accessing or mutating the "PresetAudioParams" property causes the SwiftData Macro Codes to crash, affecting both Getter and Setter. It fails with an error: "EXC_BREAKPOINT (code=1, subcode=0x1cc1698ec)" Tweaking the @Relationship marker and ModelContainer settings didn't fix the problem.
1
0
158
Apr ’25
Severe hangs with LazyHStack inside ScrollView
Hi, I got a problem with severe hangs when I use code like this on tvOS 18.2 If I try to use HStack instead of LazyHStack inside the scrollview then the problem does not occur any more but then the scroll performance is compromised and the vertical scroll is no longer that smooth. Does someone has any experience with this? Is this SwiftUI problem or am I missing something? ScrollView { LazyVStack { ForEach(0...100, id: \.self) { _ in ScrollView { LazyHStack { ForEach(0...20, id: \.self) { _ in Color.red.frame(height: 300) } } } } } }
2
0
186
Apr ’25
SwiftUI sheet ignores detent on rapid second presentation
Given a SwiftUI sheet with presentation detent(s): struct ContentView: View { @State var isSheetOpen = false var body: some View { Button("Open Sheet") { isSheetOpen = true } .sheet(isPresented: $isSheetOpen) { Color.black .presentationDetents([.medium]) } } } If you: open the sheet close it and rapidly open it again the second presentation will ignore the detent and open a full screen sheet instead. Xcode 16.3, iOS 18.4 Bug report FB17115890
2
1
114
Apr ’25
Can sections be moved/reordered within list (via onMove-style dragging)?
Consider the following example of a List view containing sections of rows. import SwiftUI struct ListSectionView: View { @State private var sectionHeaders = ["section1", "section2", "section3"] var body: some View { List { ForEach(sectionHeaders, id: \.self) { sectionHeader in Section(header: Text(sectionHeader)) { Text("1") Text("2") Text("3") } } .onMove { indices, newOffset in // ... } } } } I would like to reorder the sections within the list by dragging the respective section header to its new position in the list - similar to moving individual rows via onMove-dragging but with the sections instead of the rows. The above approach does not work. It "activates" moving the rows and then the .onMove code acts on those. The sections themselves are not moved. How can I move/reorder the sections within the list? Thanks.
1
0
186
Apr ’25
SwiftUI List Accessibility VoiceOver
I have been working on a feature, where I have a List in SwiftUI with previous and next data loading, user can scroll up and down to load previous/next page data. Recently, I faced one accessibility issue while testing voice-over, when user lands on the listing screen and swipe across the screen from navigation and when focus comes on list it should highlight the first item visible. But when user swipes back: Should it load the previous data and announce the previous item or it should go back to the navigation items? If it loads the previous item, what if the user wants to go to the navigation to switch to other actions and vice-versa? Did anyone come across this kind of issue? What can be the standard expected behavior in this case if list has both previous and next page scroll? I different tried gestures https://support.apple.com/en-in/guide/iphone/iph3e2e2281/ios, but it isn't working
2
0
145
Apr ’25
Mac Catalyst SwiftUI – . focused() not working
Hello, given this following simple SwiftUI setup: struct ContentView: View { var body: some View { CustomFocusView() } } struct CustomFocusView: View { @FocusState private var isFocused: Bool var body: some View { color .frame(width: 128, height: 128) .focusable(true) .focused($isFocused) .onTapGesture { isFocused.toggle() } .onKeyPress("a") { print("A pressed") return .handled } } var color: Color { isFocused ? .blue : .red } } If I run this via Mac – Designed for iPad, the CustomFocusView toggles focus as expected and cycles through red and blue. Now if I run this same exact code via Mac Catalyst absolutely nothing happens and so far I wasn't able to ever get this view to accept focused state. Is this expected? I would appreciate if anyone could hint me on how to get this working. Thank and best regards!
5
0
636
Apr ’25
.onTapGesture does not work when SwiftUI component sits in a flipped NSVIew
Take a look at this simple code: import Cocoa import SwiftUI struct DemoView: View { var body: some View { Text("Click me!") .onTapGesture { print("Clicked") } } } class FlippedView: NSView { override var isFlipped: Bool { return true } } class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() let stackView = NSStackView() stackView.orientation = .vertical stackView.alignment = .leading stackView.spacing = 0 stackView.translatesAutoresizingMaskIntoConstraints = false let hostView = NSHostingView(rootView: DemoView()) stackView.addArrangedSubview(hostView) let scrollView = NSScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false let flippedView = FlippedView() flippedView.addSubview(stackView) scrollView.documentView = flippedView view.addSubview(scrollView) NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: view.topAnchor), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) } } I need my scroll view to start at the very top, so i put it inside a flipped document view. But now .onTapGesture does not fire.
1
0
166
Apr ’25
Menu Bar Icon NOT Showing Up
Hi, I'm trying to make a weather menu bar app, and I want to have it so that the icon of the app in the menu changes with the actual weather, but the icon isn't showing up. There is still a space in the menu bar where I can click and open the app, it's just that the icon has disappeared. Any ideas to fix it?
1
1
639
Apr ’25
Migrating SwiftUI lifecycle to UIKit's
Hi, everyone I have an app already in production that uses SwiftUI's lifecycle (paired with an AppDelegate). Due to some specific behaviour of the app, we decided to migrate the app to use UIKit's lifecycle, adding the corresponding SceneDelegate to the app, as well as modifying the Info.plist file accordingly to accommodate to these new changes. Although everything seems to work when installing the app from zero, when installing it on top of another version, the screen goes black and the user cannot interact with the app at all unless they reinstall it completely. As I've read online, iOS is reusing the window configuration from the previous execution of the app. I know this because the AppDelegate's application(application:connectingSceneSession:options) is not being called when coming from a previous version of the app. I would love to know what can I do to make this work because, as you may understand, we cannot ask our user base to reinstall the application. Thank you very much.
7
2
1.9k
Apr ’25
Remove "copy cursor" when dragging a view in SwiftUI
Hi, Im new to SwiftUI and Im trying to implement some drag and drop functionality for some tabs in my application. Im using .draggable(_) and .dropDestination for this and the issue I have is that as I drag the view, the mouse cursor changes to the copy cursor with the green plus sign and I don't like it but I can't figure out how to avoid it. Any help would be appreciated.
1
0
78
Apr ’25
How to capture the currently pressed key when a TextField is in focus?
In the attached code snippet: struct ContentView: View { @State private var vText: String = "" var body: some View { TextField("Enter text", text: Binding( get: { vText }, set: { newValue in print("Text will change to: \(newValue)") vText = newValue } )) } } I have access to the newValue of the text-field whenever the text-field content changes, but how do I detect which key was pressed? I can manually get the diff between previous state and the new value to get the last pressed char but is there a simpler way? Also this approach won't let me detect any modifier keys (such as Alt, Ctrl etc) that the user may have pressed. Is there a pure swift-ui approach to detect these key presses?
3
0
139
Apr ’25
GroupBox breaks ability of XCTest to find popovers?
I'm using Xcode 14.3.1 on macOS 13.5, and I've managed to reproduce my issue in a trivial application. All the project settings are left at the defaults for a macOS project. It looks like using a GroupBox breaks the ability of XCTest to find popovers connected to buttons (I suspect any UI element) inside the GroupBox. The debug console output from the code below lists 15 descendants from my window with the outside-the-GroupBox popover open, and one of them is definitely a popover. With the inside-the-GroupBox popover open, my window only shows nine descendants, and no popover (the rest of the difference is the popover's contents). It's simple enough I don't see what I could be doing wrong: import SwiftUI @main struct GroupBox_Popover_DemoApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State var outsidePopoverPresented: Bool = false @State var insidePopoverPresented: Bool = false var body: some View { VStack { Button("Outside GroupBox") { outsidePopoverPresented = true } .popover(isPresented: $outsidePopoverPresented, attachmentAnchor: .point(.leading), arrowEdge: .leading) { Popover(selected: .constant("Item A"), isPresented: $outsidePopoverPresented) } .padding() GroupBox { Button("Inside GroupBox") { insidePopoverPresented = true } .popover(isPresented: $insidePopoverPresented, attachmentAnchor: .point(.leading), arrowEdge: .leading) { Popover(selected: .constant("Item B"), isPresented: $insidePopoverPresented) } .padding() } } .padding() } } struct Popover: View { @Binding var selected: String @Binding var isPresented: Bool var body: some View { VStack(alignment: .leading) { Picker("", selection: $selected) { Text("Item A").tag("Item A") Text("Item B").tag("Item B") Text("Item C").tag("Item C") } .pickerStyle(.radioGroup) HStack { Spacer() Button("Cancel") { isPresented = false } } } .padding() .frame(width: 200) } } Then in my UI tests: import XCTest final class GroupBox_Popover_DemoUITests: XCTestCase { let mainWindow = XCUIApplication().windows override func setUpWithError() throws { continueAfterFailure = false XCUIApplication().launch() } func testPopovers() { let myDescendants = mainWindow.descendants(matching: .any) mainWindow.buttons["Outside GroupBox"].click() print("Window descendants with outside popover open:") print(myDescendants.debugDescription) mainWindow.popovers.buttons["Cancel"].click() mainWindow.buttons["Inside GroupBox"].click() print("Window descendants with inside popover open:") print(myDescendants.debugDescription) mainWindow.popovers.buttons["Cancel"].click() XCTAssert(true, "Test was able to hit cancel on both popovers.") } } Any ideas? Have I missed unchecking some "Ignore anything in a GroupBox" checkbox somewhere?
3
0
826
Apr ’25
Unable to load data from Core Data in SwiftUI app (very rare)
Hey, We're loading data from Core Data, and for some reason an error is thrown. This is happening extremely rarely and we haven't been able to reproduce it. The error thrown has the following description: Åtgärden kunde inte slutföras. (ScreenGenieCore.EnrolledView.(unknown context at $10087af4c).EnrolledError fel 0.) It is occurring in an app written in SwiftUI when the user taps a button. The managed object context is initiated in app init and provided to the view using the @environment modifier. So the viewContext should always exist. Still it throws an error saying unknown context .... Any guidance or possible things to investigate would be much appreciated.
1
0
167
Apr ’25
Trigger save of a FileDocument in a DocumentGroup?
I have a DocumentGroup working with a FileDocument, and that's fine. However, when someone creates a new document I want them to have to immediately save it. This is the behavior on ipadOS and iOS from what I can understand (you select where before the file is created). There seems to be no way to do this on macOS? I basically want to have someone: create a new document enter some basic data hit "create" which saves the file then lets the user start editing it (1), (2), and (4) are done and fairly trivial. (3) seems impossible, though...? This really only needs to support macOS but any pointers would be appreciated.
0
0
288
Apr ’25
On iOS 16, VoiceOver will not speak "¥1,230" in Japanese.
In iOS 16, VoiceOver no longer speaks numbers such as “¥1,230" in Japanese, which worked correctly in iOS 15 and earlier. This is a very important bug in Accessibility support. Steps to reproduce Create iOS App Project on Xcode. (I used Xcode 14) Set the Development Localization to "Japanese" on the project settings. (to make VoiceOver speak Japanese) For example, write the following code. Build and run the App targeting the actual device, not the simulator. Actual devices running iOS 15 or earlier will correctly read out loud with VoiceOver, while iOS 16 will have some reading problems. import SwiftUI @main struct VoiceOverProblemApp: App {   var body: some Scene {     WindowGroup {       // on project settings, set the development localization to Japanese.       VStack {         // ✅ said "Hello, world!"         Text("Hello, world!")                   // ✅ said "残高 (ざんだか, zan-daka)"         Text("残高")                   // ❌ said nothing (until iOS 15 or earlier, said "千二百三十円 (せんにひゃくさんじゅうえん, sen-nihyaku-san-ju-yen)"         Text("¥1,230")                   // ❌ said wrong         //  correct (iOS 15 or earlier):  "残高は千二百三十円です (zan-daka wa sen-nihyaku-san-ju-yen desu)"         //  incorrect (iOS 16)      : "残高はです (zan-daka wa desu)"         Text("残高は ¥1,230 です")       }     }   } } The above sample code uses SwiftUI's Text but the same problem occurs with UIKit's UILabel.
1
0
1.3k
Apr ’25
Animations exported from Blender does not shoe in Reality Composer Pro
I made an animation in Blender using geometry nodes that I exported to USDC file (then I used Reality Converter to convert to USDZ) and I can see the animation when viewing from the finder but does not play after importing to RCP. Any idea how I can play the animation? Or can the animation be accessed through Xcode? Thanks!
4
0
1.1k
Apr ’25
NSDocumentController not adding "Open Recent" menu
I have a SwiftUI based app. For lots of reasons I was forced to use NSDocument instead of using DocumentGroup. I configure the main menu in my AppDelegate. It has the following code: let fileMenuItem = NSMenuItem() let fileMenu = NSMenu(title: "File") fileMenu.addItem(withTitle: "New", action: #selector(NSDocumentController.newDocument(_:)), keyEquivalent: "n") fileMenu.addItem(withTitle: "Open...", action: #selector(NSDocumentController.openDocument(_:)), keyEquivalent: "o") The New and Open work as expected. It is my understanding that the NSDocumentController should automatically add the "Open Recent" menu when it sees the Open action based on the NSDocumentController. It is not appearing. When I print the state of the recent documents using print("recent documents \(NSDocumentController.shared.recentDocumentURLs), maximum \(NSDocumentController.shared.maximumRecentDocumentCount)") I see the recent document urls and a count of 10. What can I do to make the menu appear? Thanks for the help.
5
0
288
Apr ’25
SwiftUI tvOS Accessibility VoiceOver - prevent reading all items in ScrollView over and over
Hi, I'm trying to fix tvOS view for VoiceOver accessibility feature: TabView { // 5 tabs Text(title) Button(play) ScrollView { // Live LazyHStack { 200 items } } ScrollView { // Continue watching LazyHStack { 500 items } } } When the view shows up VoiceOver reads: "Home tab 1 of 5, Item 2" - not sure why it reads Item 2 of the first cell in scroll view, maybe beacause it just got loaded by LazyHStack. VocieOver should only read "Home tab 1 of 5" When moving focus to scroll view it reads: "Live, Item 1" and after slight delay "Item 1, Item 2, Item 3, Item 4" When moving focus to second item it reads: "Item 2" and after slight delay "Item 1, Item 2, Item 3, Item 4" When moving focus to third item it reads: "Item 3" and after slight delay "Item 1, Item 2, Item 3, Item 4" It should be just reading what is focused, idealy just "Live, Item 1, 1 of 200" then after moving focus on item 2 "Item 2, 2 of 200" this time without the word "Live" because we are on the same scroll view (the same horizontal list) Currently the app is unusable, we have visually impaired testers and this rotor reading everything on the screen is totaly confusing, because users don't know where they are and what is actually focused. This is a video streaming app and we are streaming all the time, even on home page in background, binge plays one item after another, usually there is never ending Live stream playing, user can switch TV channel, but we continue to play. Voice over should only read what's focused after user interaction. Original Apple TV app does not do that, so it cannot be caused by some verbose accessibility settings. It reads correctly only focused item in scrolling lists. How do I disable reading content that is not focused? I tried: .accessibilityLabel(isFocused ? title : "") .accessibilityHidden(!isFocused) .accessibilityHidden(true) - tried on various levels in view hierarchy .accessiblityElement(children: .ignore) - even focused item is not read back by voice over .accessiblityElement(children: .ignore) - even focused item is not read back by voice over .accessiblityElement(children: .contain) - tried on various levels in view hierarchy .accessiblityElement(children: .combine) - tried on various levels in view hierarchy .accessibilityAddTraits(.isHeader) - tried on various levels in view hierarchy .accessibilityRemoveTraits(.isHeader) - tried on various levels in view hierarchy // the last 2 was basically an attempt to hack it .accessibilityRotor("", ranges []) - another hack that I tried on ScrollView, LazyHStack, also on top level view. 50+ other attempts at configuring accessibility tags attached to views. I have seen all the accessibility videos, tried all sample code projects, I haven't found a solution anywhere, internet search didn't find anything, AI didn't help as it can only provide code that someone else wrote before. Any idea how to fix this? Thanks.
1
0
169
Apr ’25
SwiftUI views lock up after background and sleep for “Designed for iPad” apps
There's an easily reproducible SwiftUI bug on macOS where an app's UI state no longer updates/re-renders for "Designed for iPad" apps (i.e. ProcessInfo.processInfo.isiOSAppOnMac == true). The bug occurs in Xcode and also if the app is running independent of Xcode. The bug occurs when: the user Hides the app (i.e. it goes into the background) the user puts the Mac to sleep (e.g. Apple menu > Sleep) a total of ~60 seconds transpires (i.e. macOS puts the app into the "suspended state") when the app is brought back into the foreground the UI no longer updates properly The only way I have found to fix this is to manually open a new actual full app window via File > New, in which case the app works fine again in the new window. The following extremely simple code in a default Xcode project illustrates the issue: import SwiftUI @main struct staleApp: App { @State private var isBright = true var body: some Scene { WindowGroup() { ZStack { (isBright ? Color.white : Color.black).ignoresSafeArea() Button("TOGGLE") { isBright.toggle(); print("TAPPED") } } .onAppear { print("\(isBright ? "light" : "dark") view appeared") } } } } For the code above, after Hiding the app and putting the computer to sleep for 60 seconds or more, the button no longer swaps views, although the print statements still appear in the console upon tapping the button. Also, while in this buggy state, i can get the view to update to the current state (i.e. the view triggered by the last tap) by manually dragging the corner of the app window to resize the window. But after resizing, the view again does not update upon button tapping until I resize the window again. so it appears the diff engine is mucked or that the Scene or WindowGroup are no longer correctly running on the main thread I have tried rebuilding the entire view hierarchy by updating .id() on views but this approach does NOT work. I have tried many other options/hacks but have not been able to reset the 'view engine' other than opening a new window manually or by using: @Environment(.openWindow) private var openWindow openWindow could be a viable solution except there's no way to programmatically close the old window for isiOSAppOnMac (@Environment(.dismissWindow) private var dismissWindow doesn't work for iOS)
0
0
172
Apr ’25
SwiftData Many-To-Many Relationship: Failed to fulfill link PendingRelationshipLink
Hi there, I got two models here: Two Models, with Many-To-Many Relationship @Model final class PresetParams: Identifiable { @Attribute(.unique) var id: UUID = UUID() var positionX: Float = 0.0 var positionY: Float = 0.0 var positionZ: Float = 0.0 var volume: Float = 1.0 @Relationship(deleteRule: .nullify, inverse: \Preset.presetAudioParams) var preset = [Preset]() init(position: SIMD3<Float>, volume: Float) { self.positionX = position.x self.positionY = position.y self.positionZ = position.z self.volume = volume self.preset = [] } var position: SIMD3<Float> { get { return SIMD3<Float>(x: positionX, y: positionY, z: positionZ) } set { positionX = newValue.x positionY = newValue.y positionZ = newValue.z } } } @Model final class Preset: Identifiable { @Attribute(.unique) var id: UUID = UUID() var presetName: String var presetDesc: String? var presetAudioParams = [PresetParams]() // Many-To-Many Relationship. init(presetName: String, presetDesc: String? = nil) { self.presetName = presetName self.presetDesc = presetDesc self.presetAudioParams = [] } } To be honest, I don't fully understand how the @Relationship thing works properly in a Many-To-Many relationship situation. Some tutorials suggest that it's required on the "One" side of an One-To-Many Relationship, while the "Many" side doesn't need it. And then there is an ObservableObject called "ModelActors" to manage all ModelActors, ModelContainer, etc. ModelActors, ModelContainer... class ModelActors: ObservableObject { static let shared: ModelActors = ModelActors() let sharedModelContainer: ModelContainer private init() { var schema = Schema([ // ... Preset.self, PresetParams.self, // ... ]) do { sharedModelContainer = try ModelContainer(for: schema, migrationPlan: MigrationPlan.self) } catch { fatalError("Could not create ModelContainer: \(error.localizedDescription)") } } } And there is a migrationPlan: MigrationPlan // MARK: V102 // typealias ... // MARK: V101 typealias Preset = AppSchemaV101.Preset typealias PresetParams = AppSchemaV101.PresetParams // MARK: V100 // typealias ... enum MigrationPlan: SchemaMigrationPlan { static var schemas: [VersionedSchema.Type] { [ AppSchemaV100.self, AppSchemaV101.self, AppSchemaV102.self, ] } static var stages: [MigrationStage] { [AppMigrateV100toV101, AppMigrateV101toV102] } static let AppMigrateV100toV101 = MigrationStage.lightweight(fromVersion: AppSchemaV100.self, toVersion: AppSchemaV101.self) static let AppMigrateV101toV102 = MigrationStage.lightweight(fromVersion: AppSchemaV101.self, toVersion: AppSchemaV102.self) } // MARK: Here is the AppSchemaV101 enum AppSchemaV101: VersionedSchema { static var versionIdentifier: Schema.Version = Schema.Version(1, 0, 1) static var models: [any PersistentModel.Type] { return [ // ... Preset.self, PresetParams.self ] } } Fails on iOS 18.3.x: "Failed to fulfill link PendingRelationshipLink" So I expected the SwiftData subsystem to work correctly with version control. A good news is that on iOS 18.1 it does work. But it fails on iOS 18.3.x with a fatal Error: "SwiftData/SchemaCoreData.swift:581: Fatal error: Failed to fulfill link PendingRelationshipLink(relationshipDescription: (<NSRelationshipDescription: 0x30377fe80>), name preset, isOptional 0, isTransient 0, entity PresetParams, renamingIdentifier preset, validation predicates (), warnings (), versionHashModifier (null)userInfo {}, destination entity Preset, inverseRelationship (null), minCount 0, maxCount 0, isOrdered 0, deleteRule 1, destinationEntityName: "Preset", inverseRelationshipName: Optional("presetAudioParams")), couldn't find inverse relationship 'Preset.presetAudioParams' in model" Fails on iOS 17.5: Another Error I tested it on iOS 17.5 and found another issue: Accessing or mutating the "PresetAudioParams" property causes the SwiftData Macro Codes to crash, affecting both Getter and Setter. It fails with an error: "EXC_BREAKPOINT (code=1, subcode=0x1cc1698ec)" Tweaking the @Relationship marker and ModelContainer settings didn't fix the problem.
Replies
1
Boosts
0
Views
158
Activity
Apr ’25
Severe hangs with LazyHStack inside ScrollView
Hi, I got a problem with severe hangs when I use code like this on tvOS 18.2 If I try to use HStack instead of LazyHStack inside the scrollview then the problem does not occur any more but then the scroll performance is compromised and the vertical scroll is no longer that smooth. Does someone has any experience with this? Is this SwiftUI problem or am I missing something? ScrollView { LazyVStack { ForEach(0...100, id: \.self) { _ in ScrollView { LazyHStack { ForEach(0...20, id: \.self) { _ in Color.red.frame(height: 300) } } } } } }
Replies
2
Boosts
0
Views
186
Activity
Apr ’25
SwiftUI sheet ignores detent on rapid second presentation
Given a SwiftUI sheet with presentation detent(s): struct ContentView: View { @State var isSheetOpen = false var body: some View { Button("Open Sheet") { isSheetOpen = true } .sheet(isPresented: $isSheetOpen) { Color.black .presentationDetents([.medium]) } } } If you: open the sheet close it and rapidly open it again the second presentation will ignore the detent and open a full screen sheet instead. Xcode 16.3, iOS 18.4 Bug report FB17115890
Replies
2
Boosts
1
Views
114
Activity
Apr ’25
Can sections be moved/reordered within list (via onMove-style dragging)?
Consider the following example of a List view containing sections of rows. import SwiftUI struct ListSectionView: View { @State private var sectionHeaders = ["section1", "section2", "section3"] var body: some View { List { ForEach(sectionHeaders, id: \.self) { sectionHeader in Section(header: Text(sectionHeader)) { Text("1") Text("2") Text("3") } } .onMove { indices, newOffset in // ... } } } } I would like to reorder the sections within the list by dragging the respective section header to its new position in the list - similar to moving individual rows via onMove-dragging but with the sections instead of the rows. The above approach does not work. It "activates" moving the rows and then the .onMove code acts on those. The sections themselves are not moved. How can I move/reorder the sections within the list? Thanks.
Replies
1
Boosts
0
Views
186
Activity
Apr ’25
SwiftUI List Accessibility VoiceOver
I have been working on a feature, where I have a List in SwiftUI with previous and next data loading, user can scroll up and down to load previous/next page data. Recently, I faced one accessibility issue while testing voice-over, when user lands on the listing screen and swipe across the screen from navigation and when focus comes on list it should highlight the first item visible. But when user swipes back: Should it load the previous data and announce the previous item or it should go back to the navigation items? If it loads the previous item, what if the user wants to go to the navigation to switch to other actions and vice-versa? Did anyone come across this kind of issue? What can be the standard expected behavior in this case if list has both previous and next page scroll? I different tried gestures https://support.apple.com/en-in/guide/iphone/iph3e2e2281/ios, but it isn't working
Replies
2
Boosts
0
Views
145
Activity
Apr ’25
Mac Catalyst SwiftUI – . focused() not working
Hello, given this following simple SwiftUI setup: struct ContentView: View { var body: some View { CustomFocusView() } } struct CustomFocusView: View { @FocusState private var isFocused: Bool var body: some View { color .frame(width: 128, height: 128) .focusable(true) .focused($isFocused) .onTapGesture { isFocused.toggle() } .onKeyPress("a") { print("A pressed") return .handled } } var color: Color { isFocused ? .blue : .red } } If I run this via Mac – Designed for iPad, the CustomFocusView toggles focus as expected and cycles through red and blue. Now if I run this same exact code via Mac Catalyst absolutely nothing happens and so far I wasn't able to ever get this view to accept focused state. Is this expected? I would appreciate if anyone could hint me on how to get this working. Thank and best regards!
Replies
5
Boosts
0
Views
636
Activity
Apr ’25
.onTapGesture does not work when SwiftUI component sits in a flipped NSVIew
Take a look at this simple code: import Cocoa import SwiftUI struct DemoView: View { var body: some View { Text("Click me!") .onTapGesture { print("Clicked") } } } class FlippedView: NSView { override var isFlipped: Bool { return true } } class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() let stackView = NSStackView() stackView.orientation = .vertical stackView.alignment = .leading stackView.spacing = 0 stackView.translatesAutoresizingMaskIntoConstraints = false let hostView = NSHostingView(rootView: DemoView()) stackView.addArrangedSubview(hostView) let scrollView = NSScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false let flippedView = FlippedView() flippedView.addSubview(stackView) scrollView.documentView = flippedView view.addSubview(scrollView) NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: view.topAnchor), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) } } I need my scroll view to start at the very top, so i put it inside a flipped document view. But now .onTapGesture does not fire.
Replies
1
Boosts
0
Views
166
Activity
Apr ’25
Menu Bar Icon NOT Showing Up
Hi, I'm trying to make a weather menu bar app, and I want to have it so that the icon of the app in the menu changes with the actual weather, but the icon isn't showing up. There is still a space in the menu bar where I can click and open the app, it's just that the icon has disappeared. Any ideas to fix it?
Replies
1
Boosts
1
Views
639
Activity
Apr ’25
Migrating SwiftUI lifecycle to UIKit's
Hi, everyone I have an app already in production that uses SwiftUI's lifecycle (paired with an AppDelegate). Due to some specific behaviour of the app, we decided to migrate the app to use UIKit's lifecycle, adding the corresponding SceneDelegate to the app, as well as modifying the Info.plist file accordingly to accommodate to these new changes. Although everything seems to work when installing the app from zero, when installing it on top of another version, the screen goes black and the user cannot interact with the app at all unless they reinstall it completely. As I've read online, iOS is reusing the window configuration from the previous execution of the app. I know this because the AppDelegate's application(application:connectingSceneSession:options) is not being called when coming from a previous version of the app. I would love to know what can I do to make this work because, as you may understand, we cannot ask our user base to reinstall the application. Thank you very much.
Replies
7
Boosts
2
Views
1.9k
Activity
Apr ’25
Remove "copy cursor" when dragging a view in SwiftUI
Hi, Im new to SwiftUI and Im trying to implement some drag and drop functionality for some tabs in my application. Im using .draggable(_) and .dropDestination for this and the issue I have is that as I drag the view, the mouse cursor changes to the copy cursor with the green plus sign and I don't like it but I can't figure out how to avoid it. Any help would be appreciated.
Replies
1
Boosts
0
Views
78
Activity
Apr ’25
How to capture the currently pressed key when a TextField is in focus?
In the attached code snippet: struct ContentView: View { @State private var vText: String = "" var body: some View { TextField("Enter text", text: Binding( get: { vText }, set: { newValue in print("Text will change to: \(newValue)") vText = newValue } )) } } I have access to the newValue of the text-field whenever the text-field content changes, but how do I detect which key was pressed? I can manually get the diff between previous state and the new value to get the last pressed char but is there a simpler way? Also this approach won't let me detect any modifier keys (such as Alt, Ctrl etc) that the user may have pressed. Is there a pure swift-ui approach to detect these key presses?
Replies
3
Boosts
0
Views
139
Activity
Apr ’25
GroupBox breaks ability of XCTest to find popovers?
I'm using Xcode 14.3.1 on macOS 13.5, and I've managed to reproduce my issue in a trivial application. All the project settings are left at the defaults for a macOS project. It looks like using a GroupBox breaks the ability of XCTest to find popovers connected to buttons (I suspect any UI element) inside the GroupBox. The debug console output from the code below lists 15 descendants from my window with the outside-the-GroupBox popover open, and one of them is definitely a popover. With the inside-the-GroupBox popover open, my window only shows nine descendants, and no popover (the rest of the difference is the popover's contents). It's simple enough I don't see what I could be doing wrong: import SwiftUI @main struct GroupBox_Popover_DemoApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State var outsidePopoverPresented: Bool = false @State var insidePopoverPresented: Bool = false var body: some View { VStack { Button("Outside GroupBox") { outsidePopoverPresented = true } .popover(isPresented: $outsidePopoverPresented, attachmentAnchor: .point(.leading), arrowEdge: .leading) { Popover(selected: .constant("Item A"), isPresented: $outsidePopoverPresented) } .padding() GroupBox { Button("Inside GroupBox") { insidePopoverPresented = true } .popover(isPresented: $insidePopoverPresented, attachmentAnchor: .point(.leading), arrowEdge: .leading) { Popover(selected: .constant("Item B"), isPresented: $insidePopoverPresented) } .padding() } } .padding() } } struct Popover: View { @Binding var selected: String @Binding var isPresented: Bool var body: some View { VStack(alignment: .leading) { Picker("", selection: $selected) { Text("Item A").tag("Item A") Text("Item B").tag("Item B") Text("Item C").tag("Item C") } .pickerStyle(.radioGroup) HStack { Spacer() Button("Cancel") { isPresented = false } } } .padding() .frame(width: 200) } } Then in my UI tests: import XCTest final class GroupBox_Popover_DemoUITests: XCTestCase { let mainWindow = XCUIApplication().windows override func setUpWithError() throws { continueAfterFailure = false XCUIApplication().launch() } func testPopovers() { let myDescendants = mainWindow.descendants(matching: .any) mainWindow.buttons["Outside GroupBox"].click() print("Window descendants with outside popover open:") print(myDescendants.debugDescription) mainWindow.popovers.buttons["Cancel"].click() mainWindow.buttons["Inside GroupBox"].click() print("Window descendants with inside popover open:") print(myDescendants.debugDescription) mainWindow.popovers.buttons["Cancel"].click() XCTAssert(true, "Test was able to hit cancel on both popovers.") } } Any ideas? Have I missed unchecking some "Ignore anything in a GroupBox" checkbox somewhere?
Replies
3
Boosts
0
Views
826
Activity
Apr ’25
Unable to load data from Core Data in SwiftUI app (very rare)
Hey, We're loading data from Core Data, and for some reason an error is thrown. This is happening extremely rarely and we haven't been able to reproduce it. The error thrown has the following description: Åtgärden kunde inte slutföras. (ScreenGenieCore.EnrolledView.(unknown context at $10087af4c).EnrolledError fel 0.) It is occurring in an app written in SwiftUI when the user taps a button. The managed object context is initiated in app init and provided to the view using the @environment modifier. So the viewContext should always exist. Still it throws an error saying unknown context .... Any guidance or possible things to investigate would be much appreciated.
Replies
1
Boosts
0
Views
167
Activity
Apr ’25
List Outline View Not Using Accent Color on Disclosure Caret for visionOS
I’ve submitted the following feedback: FB13820942 (List Outline View Not Using Accent Color on Disclosure Caret for visionOS) I’d appreciate help on this to see if I’m doing something wrong or indeed it’s the way visionOS currently works and it’s a suggested feedback.
Replies
3
Boosts
0
Views
725
Activity
Apr ’25
Trigger save of a FileDocument in a DocumentGroup?
I have a DocumentGroup working with a FileDocument, and that's fine. However, when someone creates a new document I want them to have to immediately save it. This is the behavior on ipadOS and iOS from what I can understand (you select where before the file is created). There seems to be no way to do this on macOS? I basically want to have someone: create a new document enter some basic data hit "create" which saves the file then lets the user start editing it (1), (2), and (4) are done and fairly trivial. (3) seems impossible, though...? This really only needs to support macOS but any pointers would be appreciated.
Replies
0
Boosts
0
Views
288
Activity
Apr ’25
On iOS 16, VoiceOver will not speak "¥1,230" in Japanese.
In iOS 16, VoiceOver no longer speaks numbers such as “¥1,230" in Japanese, which worked correctly in iOS 15 and earlier. This is a very important bug in Accessibility support. Steps to reproduce Create iOS App Project on Xcode. (I used Xcode 14) Set the Development Localization to "Japanese" on the project settings. (to make VoiceOver speak Japanese) For example, write the following code. Build and run the App targeting the actual device, not the simulator. Actual devices running iOS 15 or earlier will correctly read out loud with VoiceOver, while iOS 16 will have some reading problems. import SwiftUI @main struct VoiceOverProblemApp: App {   var body: some Scene {     WindowGroup {       // on project settings, set the development localization to Japanese.       VStack {         // ✅ said "Hello, world!"         Text("Hello, world!")                   // ✅ said "残高 (ざんだか, zan-daka)"         Text("残高")                   // ❌ said nothing (until iOS 15 or earlier, said "千二百三十円 (せんにひゃくさんじゅうえん, sen-nihyaku-san-ju-yen)"         Text("¥1,230")                   // ❌ said wrong         //  correct (iOS 15 or earlier):  "残高は千二百三十円です (zan-daka wa sen-nihyaku-san-ju-yen desu)"         //  incorrect (iOS 16)      : "残高はです (zan-daka wa desu)"         Text("残高は ¥1,230 です")       }     }   } } The above sample code uses SwiftUI's Text but the same problem occurs with UIKit's UILabel.
Replies
1
Boosts
0
Views
1.3k
Activity
Apr ’25
Animations exported from Blender does not shoe in Reality Composer Pro
I made an animation in Blender using geometry nodes that I exported to USDC file (then I used Reality Converter to convert to USDZ) and I can see the animation when viewing from the finder but does not play after importing to RCP. Any idea how I can play the animation? Or can the animation be accessed through Xcode? Thanks!
Replies
4
Boosts
0
Views
1.1k
Activity
Apr ’25
NSDocumentController not adding "Open Recent" menu
I have a SwiftUI based app. For lots of reasons I was forced to use NSDocument instead of using DocumentGroup. I configure the main menu in my AppDelegate. It has the following code: let fileMenuItem = NSMenuItem() let fileMenu = NSMenu(title: "File") fileMenu.addItem(withTitle: "New", action: #selector(NSDocumentController.newDocument(_:)), keyEquivalent: "n") fileMenu.addItem(withTitle: "Open...", action: #selector(NSDocumentController.openDocument(_:)), keyEquivalent: "o") The New and Open work as expected. It is my understanding that the NSDocumentController should automatically add the "Open Recent" menu when it sees the Open action based on the NSDocumentController. It is not appearing. When I print the state of the recent documents using print("recent documents \(NSDocumentController.shared.recentDocumentURLs), maximum \(NSDocumentController.shared.maximumRecentDocumentCount)") I see the recent document urls and a count of 10. What can I do to make the menu appear? Thanks for the help.
Replies
5
Boosts
0
Views
288
Activity
Apr ’25
SwiftUI tvOS Accessibility VoiceOver - prevent reading all items in ScrollView over and over
Hi, I'm trying to fix tvOS view for VoiceOver accessibility feature: TabView { // 5 tabs Text(title) Button(play) ScrollView { // Live LazyHStack { 200 items } } ScrollView { // Continue watching LazyHStack { 500 items } } } When the view shows up VoiceOver reads: "Home tab 1 of 5, Item 2" - not sure why it reads Item 2 of the first cell in scroll view, maybe beacause it just got loaded by LazyHStack. VocieOver should only read "Home tab 1 of 5" When moving focus to scroll view it reads: "Live, Item 1" and after slight delay "Item 1, Item 2, Item 3, Item 4" When moving focus to second item it reads: "Item 2" and after slight delay "Item 1, Item 2, Item 3, Item 4" When moving focus to third item it reads: "Item 3" and after slight delay "Item 1, Item 2, Item 3, Item 4" It should be just reading what is focused, idealy just "Live, Item 1, 1 of 200" then after moving focus on item 2 "Item 2, 2 of 200" this time without the word "Live" because we are on the same scroll view (the same horizontal list) Currently the app is unusable, we have visually impaired testers and this rotor reading everything on the screen is totaly confusing, because users don't know where they are and what is actually focused. This is a video streaming app and we are streaming all the time, even on home page in background, binge plays one item after another, usually there is never ending Live stream playing, user can switch TV channel, but we continue to play. Voice over should only read what's focused after user interaction. Original Apple TV app does not do that, so it cannot be caused by some verbose accessibility settings. It reads correctly only focused item in scrolling lists. How do I disable reading content that is not focused? I tried: .accessibilityLabel(isFocused ? title : "") .accessibilityHidden(!isFocused) .accessibilityHidden(true) - tried on various levels in view hierarchy .accessiblityElement(children: .ignore) - even focused item is not read back by voice over .accessiblityElement(children: .ignore) - even focused item is not read back by voice over .accessiblityElement(children: .contain) - tried on various levels in view hierarchy .accessiblityElement(children: .combine) - tried on various levels in view hierarchy .accessibilityAddTraits(.isHeader) - tried on various levels in view hierarchy .accessibilityRemoveTraits(.isHeader) - tried on various levels in view hierarchy // the last 2 was basically an attempt to hack it .accessibilityRotor("", ranges []) - another hack that I tried on ScrollView, LazyHStack, also on top level view. 50+ other attempts at configuring accessibility tags attached to views. I have seen all the accessibility videos, tried all sample code projects, I haven't found a solution anywhere, internet search didn't find anything, AI didn't help as it can only provide code that someone else wrote before. Any idea how to fix this? Thanks.
Replies
1
Boosts
0
Views
169
Activity
Apr ’25
SwiftUI views lock up after background and sleep for “Designed for iPad” apps
There's an easily reproducible SwiftUI bug on macOS where an app's UI state no longer updates/re-renders for "Designed for iPad" apps (i.e. ProcessInfo.processInfo.isiOSAppOnMac == true). The bug occurs in Xcode and also if the app is running independent of Xcode. The bug occurs when: the user Hides the app (i.e. it goes into the background) the user puts the Mac to sleep (e.g. Apple menu > Sleep) a total of ~60 seconds transpires (i.e. macOS puts the app into the "suspended state") when the app is brought back into the foreground the UI no longer updates properly The only way I have found to fix this is to manually open a new actual full app window via File > New, in which case the app works fine again in the new window. The following extremely simple code in a default Xcode project illustrates the issue: import SwiftUI @main struct staleApp: App { @State private var isBright = true var body: some Scene { WindowGroup() { ZStack { (isBright ? Color.white : Color.black).ignoresSafeArea() Button("TOGGLE") { isBright.toggle(); print("TAPPED") } } .onAppear { print("\(isBright ? "light" : "dark") view appeared") } } } } For the code above, after Hiding the app and putting the computer to sleep for 60 seconds or more, the button no longer swaps views, although the print statements still appear in the console upon tapping the button. Also, while in this buggy state, i can get the view to update to the current state (i.e. the view triggered by the last tap) by manually dragging the corner of the app window to resize the window. But after resizing, the view again does not update upon button tapping until I resize the window again. so it appears the diff engine is mucked or that the Scene or WindowGroup are no longer correctly running on the main thread I have tried rebuilding the entire view hierarchy by updating .id() on views but this approach does NOT work. I have tried many other options/hacks but have not been able to reset the 'view engine' other than opening a new window manually or by using: @Environment(.openWindow) private var openWindow openWindow could be a viable solution except there's no way to programmatically close the old window for isiOSAppOnMac (@Environment(.dismissWindow) private var dismissWindow doesn't work for iOS)
Replies
0
Boosts
0
Views
172
Activity
Apr ’25