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

SwiftUI Documentation

Post

Replies

Boosts

Views

Activity

document-based sample code doesn't work... work around?
I just tried the "Building a document-based app with SwiftUI" sample code for iOS 18. https://developer.apple.com/documentation/swiftui/building-a-document-based-app-with-swiftui I can create a document and then close it. But once I open it back up, I can't navigate back to the documents browser. It also struggles to open documents (I would tap multiple times and nothing happens). This happens on both simulator and device. Will file a bug, but anyone know of a work-around? I can't use a document browser that is this broken.
1
1
186
3w
send data or share variables between Immersive view and "attached" 2D view
I have an immersive space with a RealityKit view which is running an ARKitSession to access main camera frames. This frame is processed with custom computer vision algorithms (and deep learning models). There is a 3D Entity in the RealityKit view which I'm trying to place in the world, but I want to debug my (2D) algorithms in an "attached" view (display images in windows). How to I send/share data or variables between the views (and and spaces)?
1
0
200
3w
Identify what is being dragged globally
I would like to implement the same kind of behavior as the Dropoverapp application, specifically being able to perform a specific action when files are dragged (such as opening a window, for example). I have written the code below to capture the mouse coordinates, drag, drop, and click globally. However, I don't know how to determine the nature of what is being dropped. Do you have any ideas on how to detect the nature of what is being dragged outside the application's scope? Here is my current code: import SwiftUI import CoreGraphics struct ContentView: View { @State private var mouseX: CGFloat = 0.0 @State private var mouseY: CGFloat = 0.0 @State private var isClicked: Bool = false @State private var isDragging: Bool = false private var mouseTracker = MouseTracker.shared var body: some View { VStack { Text("Mouse coordinates: \(mouseX, specifier: "%.2f"), \(mouseY, specifier: "%.2f")") .padding() Text(isClicked ? "Mouse is clicked" : "Mouse is not clicked") .padding() Text(isDragging ? "Mouse is dragging" : "Mouse is not dragging") .padding() } .frame(width: 400, height: 200) .onAppear { mouseTracker.startTracking { newMouseX, newMouseY, newIsClicked, newIsDragging in self.mouseX = newMouseX self.mouseY = newMouseY self.isClicked = newIsClicked self.isDragging = newIsDragging } } } } class MouseTracker { static let shared = MouseTracker() private var eventTap: CFMachPort? private var runLoopSource: CFRunLoopSource? private var isClicked: Bool = false private var isDragging: Bool = false private var callback: ((CGFloat, CGFloat, Bool, Bool) -> Void)? func startTracking(callback: @escaping (CGFloat, CGFloat, Bool, Bool) -> Void) { self.callback = callback let mask: CGEventMask = (1 << CGEventType.mouseMoved.rawValue) | (1 << CGEventType.leftMouseDown.rawValue) | (1 << CGEventType.leftMouseUp.rawValue) | (1 << CGEventType.leftMouseDragged.rawValue) // Pass 'self' via 'userInfo' let selfPointer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) guard let eventTap = CGEvent.tapCreate( tap: .cghidEventTap, place: .headInsertEventTap, options: .defaultTap, eventsOfInterest: mask, callback: MouseTracker.mouseEventCallback, userInfo: selfPointer ) else { print("Failed to create event tap") return } self.eventTap = eventTap runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0) CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes) CGEvent.tapEnable(tap: eventTap, enable: true) } // Static callback function private static let mouseEventCallback: CGEventTapCallBack = { _, eventType, event, userInfo in guard let userInfo = userInfo else { return Unmanaged.passUnretained(event) } // Retrieve the instance of MouseTracker from userInfo let tracker = Unmanaged<MouseTracker>.fromOpaque(userInfo).takeUnretainedValue() let location = NSEvent.mouseLocation // Update the click and drag state switch eventType { case .leftMouseDown: tracker.isClicked = true tracker.isDragging = false case .leftMouseUp: tracker.isClicked = false tracker.isDragging = false case .leftMouseDragged: tracker.isDragging = true default: break } // Call the callback on the main thread DispatchQueue.main.async { tracker.callback?(location.x, location.y, tracker.isClicked, tracker.isDragging) } return Unmanaged.passUnretained(event) } }
0
0
127
3w
SwiftUI 'List' performance issue on macOS
Hi, When using SwiftUI ‘List’ with a large number of elements (4000+), I noticed a significant performance issue if extracting the views inside the ‘ForEach’ block into their own subview class. It affects scrolling performance, and using the scroll handle in the scrollbar causes stutters and beachballs. This seems to happen on macOS only ... the same project works fine on iOS. Here's an example of what I mean: List (selection: $multiSelectedContacts) { ForEach(items) { item in // 1. this subview is the problem ... replace it with the contents of the subview, and it works fine PlainContentItemView(item: item) // 2. Uncomment this part for it to work fine (and comment out PlainContentItemView above) /*HStack { if let timestamp = item.timestamp, let itemNumber = item.itemNumber { Text("\(itemNumber) - \(timestamp, formatter: itemFormatter)") } }*/ } } struct PlainContentItemView: View { let item: Item var body: some View { HStack { if let timestamp = item.timestamp, let itemNumber = item.itemNumber { Text("\(itemNumber) - \(timestamp, formatter: itemFormatter)") } } } } Item is a NSManagedObject subclass, and conforms to Identifiable by using the objectID string value. With this, scrolling up and down using the scrolling handle, causes stuttering scrolling and can beachball on my machine (MacBook Pro M1). If I comment out the ‘PlainContentItemView’ and just use the HStack directly (which is what was extracted to ‘PlainContentItemView’), the performance noticeably improves, and I can scroll up and down smoothly. Is this just a bug with SwiftUI, and/or can I do something to improve this?
0
0
183
3w
Pre-initialization of views?
It seems somewhere around the update to xcode 16 and swift 6, apple may have decided to change when view are initialized. My views suddenly pre-initialize before opening the view. Is this a new feature? I have a regular VStack or a LazyVStack, with ForEach and navigationLinks inside. Those views that the navigation link takes you to are initializing as I am scrolling in the VStack. This is absurd, there is so much overhead going on in these views to be initialized. I can think of a fix which is to implement init functions in the onAppear, and keep a property to track if view already appeared. But before that I just want to make sure this is a new feature and not some mishap on my part, and if there is a way to disable it. Thank you.
2
0
127
3w
Issue with High-Quality Images Stalling in LazyVStack with Kingfisher
Hi there! I’m experiencing an issue while loading images with Kingfisher in a LazyVStack containing around 500 items. When I use low-resolution images, everything loads correctly. However, when I switch to higher quality images, only some of them load successfully, while the rest remain stuck in a loading state, and I see the following log: nw_connection_add_timestamp_locked_on_nw_queue [C1] Hit maximum timestamp count, will start dropping events Interestingly, if I switch from WiFi to 5G, the images start loading again, but the loading stalls once more after a few additional images. Could you help me understand why this happens with high-quality images and how to resolve it? Thank you!
1
0
425
3w
SizeClasses, really?
I have an app with looks at the @Environment(\.horizontalSizeClass) variable and it's mate vertical. On the iPhone 16 sim, if I'm in portrait orientation, It says my vertical class is .regular and horizontal is .compact. If I rotate to landscape, it says vertical is now compact, and horizontal is still compact. That seems inconsistent. I'm trying to wrap my head around designing for size class, how am I supposed to think about this? What I want is two areas of the screen: The main area, which shows a graphic, and a much smaller control and data area, which has a button or two and a very narrow text display, which in my current app counts from 1 to 4. The button area These areas ought never move from where they are, but their contents ought to rotate in place to reflect the orientation. If portrait, the button area is on the bottom, if landscapeLeft, the button are is to the right, if landscapeRight, the button area is to the left. This currently sort of works if I test for the max of height or width from a Geometry Reader, but it doesn't handle landscapeRight or portraitUpsideDown correctly.
1
0
138
3w
Type Eraser for Container
Hi all, Is this allowed: environment(\.container, MyContainer() as Any) While injecting Model container into the environment we use Type . Is there any universal injection type that can inject container as set of any types rather than array similar to navigationPath() type-eraser ?
3
0
185
3w
Issue with .itemProvider on macOS 15.1
I have a List with draggable items. According to this thread (https://developer.apple.com/forums/thread/664469) I had to use .itemProvider instead of .onDrag, because otherwise the selection of the list will not work anymore. The items in my list refer to a file URL. So the dragging allowed to copy the files to the destination of the drag & drop. Therefore I used this code .itemProvider { let url = ....... // get the url with an internal function return NSItemProvider(object: url as NSURL) } Since the update to macOS 15.1 this way isn't working anymore. It just happens nothing. I also tried to use .itemProvider { let url = .... return NSItemProvider(contentsOf: url) ?? NSItemProvider(object: url as NSURL) } but this doesn't work too. The same way with .onDrag works btw. .onDrag { let url = ....... // get the url with an internal function return NSItemProvider(object: url as NSURL) } but as I wrote, this will break the possibility to select or to use the primaryAction of the .contextMenu. Is this a bug? Or is my approach wrong and is there an alternative?
5
0
170
3w
iOS18.1 Issue SwiftUI’s App
The interactiveDismissDisabled() function in SwiftUI's Sheet no longer works as expected in iOS 18.1 (22B83). It was working as expected until iOS 18.0.1. Are there any other users experiencing the same issue? struct ContentView: View { @State private var openSheet = false var body: some View { NavigationStack { Button("Open") { openSheet = true } .sheet(isPresented: $openSheet) { SheetView() } } } } struct SheetView: View { @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { Text("This is the Sheet") .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Cancel") { dismiss() } } } .interactiveDismissDisabled() } } } Supplementary information: In iOS 18.1, even Apple's native Journal app allows users to swipe-to-dismiss the sheet when creating a new entry. Previously, a confirmation dialog would be displayed, but this is no longer the case.​​​​​​​​​​​​​​​​
2
1
307
3w
'Save to Files' doesn't work with ShareLink with FileRepresentation
I want to use ShareLink+FileRepresentation to save a small text file to my iPhone with the steps below. Tap [Share...] to display the share sheet. This sheet contains [Save to Files]. Tap [Save to Files]. A black sheet is displayed, but it disappears instantly. In step 3, I was expecting a browser to be displayed to select the location where the file will be saved. But in fact, a black sheet appears, which quickly disappears. The implemented code is as follows. import SwiftUI @main struct SLSandboxApp: App { var body: some Scene { WindowGroup { let title = Text("File Output") let numListString = "123,456,789" let numListFileName = "numlist.csv" let tagListFile = TextFile(content: numListString, filename: numListFileName) ShareView(title: title, fileToShare: tagListFile, messageToPreview: numListFileName) } } } struct ShareView: View { let title: Text let fileToShare: TextFile let messageToPreview: String var body: some View { ShareLink(item: self.fileToShare, preview: SharePreview(self.messageToPreview)) } } struct TextFile: Transferable { let content: String let filename: String static var transferRepresentation: some TransferRepresentation { FileRepresentation(exportedContentType: .data) { textFile in let data = textFile.content.data(using: .utf8) ?? Data() let tempDirectory = FileManager.default.temporaryDirectory let fileURL = tempDirectory.appendingPathComponent(textFile.filename) try data.write(to: fileURL) return SentTransferredFile(fileURL) } } } The development environment is as follows. Xcode 15.4 (Deployment Target = iOS Deployment Target 17.5) macOS 14.6.1 The execution environment is as follows. iPhone SE Gen3 17.7 The following is a console log from the time the application was launched to the time when the share sheet was displayed by tapping [Share...]. Error acquiring assertion: &lt;Error Domain=RBSServiceErrorDomain Code=1 "(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)" UserInfo={NSLocalizedFailureReason=(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)}&gt; (501) personaAttributesForPersonaType for type:0 failed with error Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.mobile.usermanagerd.xpc was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.apple.mobile.usermanagerd.xpc was invalidated: failed at lookup with error 159 - Sandbox restriction.} Received port for identifier response: &lt;(null)&gt; with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false} elapsedCPUTimeForFrontBoard couldn't generate a task port Received port for identifier response: &lt;(null)&gt; with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false} elapsedCPUTimeForFrontBoard couldn't generate a task port Received port for identifier response: &lt;(null)&gt; with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false} elapsedCPUTimeForFrontBoard couldn't generate a task port The following is the console log that was written when I tapped [Save to file] on the share sheet. cancelled request - error: The operation couldn’t be completed. Invalid argument What modifications should I make to the code to get the expected result?
0
0
180
3w
SwiftUI TabView lifecycle is weird
I tested the life cycle of TabView and its sub-Views through the demo and found something strange. Please help analyze it. Thank you. The demo project is here https://feedbackassistant.apple.com/feedback/15629780 Operation steps: Step 1: launch app Step 2: click Login button the below log is correct SettingsViewModel init HomeViewModel init HomeView appear Step 3: click Settings tab SettingsView appear (correct) Step 4: click Refresh TabView button the below log is incorrect Refresh TabView StatusViewModel init AccountViewModel init StatusViewModel init (weird) AccountViewModel init (weird) HomeView appear (weird) StatusViewModel deinit AccountViewModel deinit AccountView appear SettingsViewModel deinit HomeViewModel deinit Expect log: Refresh TabView SettingsViewModel deinit HomeViewModel deinit StatusViewModel init AccountViewModel init AccountView appear
0
0
166
3w
UIHostingConfiguration + MainActor.assumeIsolated?
I'm trying to use a SwiftUI view as UICalendarView decoration and I get Call to main actor-isolated instance method 'makeContentView()' in a synchronous nonisolated context; this is an error in the Swift 6 language mode in the following code: class Coordinator: NSObject, UICalendarViewDelegate { func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? { .customView { UIHostingConfiguration { ... } .makeContentView() } } } I've fixed using MainActor.assumeIsolated but is this the correct approach or is there a better one? class Coordinator: NSObject, UICalendarViewDelegate { func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? { .customView { MainActor.assumeIsolated { UIHostingConfiguration { ... } .makeContentView() } } } }
1
0
167
3w
Preventing Swipe-to-Dismiss on SwiftUI Sheets no longer working in iOS 18.1 (22B83)
The interactiveDismissDisabled() function in SwiftUI's Sheet no longer works as expected in iOS 18.1 (22B83). It was working as expected until iOS 18.0.1. Are there any other users experiencing the same issue? struct ContentView: View { @State private var openSheet = false var body: some View { NavigationStack { Button("Open") { openSheet = true } .sheet(isPresented: $openSheet) { SheetView() } } } } struct SheetView: View { @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { Text("This is the Sheet") .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Cancel") { dismiss() } } } .interactiveDismissDisabled() } } } Supplementary information: In iOS 18.1, even Apple's native Journal app allows users to swipe-to-dismiss the sheet when creating a new entry. Previously, a confirmation dialog would be displayed, but this is no longer the case.​​​​​​​​​​​​​​​​
1
0
186
3w
Is this log noise? "CoreSVG: Error: NULL ref passed to getObjectCoreSVG: Error: NULL ref passed to getObject"
Before I waste time creating an Apple Developer Support ticket, I’m hoping an Apple DTS engineer can confirm if this is just log noise. Here’s the code: import SwiftUI struct ContentView: View { @State private var editMode: EditMode = .inactive @State private var items = ["Item 1", "Item 2", "Item 3"] var body: some View { NavigationStack { List { ForEach(items, id: \.self) { item in Text(item) } .onDelete { indexSet in items.remove(atOffsets: indexSet) } } .environment(\.editMode, $editMode) .toolbar { ToolbarItem(placement: .topBarTrailing) { EditButton() .environment(\.editMode, $editMode) } } } } } #Preview { ContentView() } When you run this code and tap Edit, you’ll initially get: CoreSVG has logged an error. Set environment variabe [sic] "CORESVG_VERBOSE" to learn more. After setting CORESVG_VERBOSE = YES, you’ll see: CoreSVG: Error: NULL ref passed to getObjectCoreSVG: Error: NULL ref passed to getObject This error only appears the first time Edit is tapped after a build and run. It won't happen again, even after force-quitting and reopening the app. The issue also only happens on iOS 18.0 and 18.1—I can’t reproduce it on iOS 17.5. Fortunately, it doesn’t seem to cause any negative side effects. Is this just log noise?
1
3
422
3w
Lose my variables when my watch turn off
Hello guys, I have such a big coding problem since a half year now about data saving. I have a fitness app where we can add our exercices depend of the muscle, so you can choose it and then select your weight and number of repetitions and valid your exercise. But when I do my exercises and my watch screen is also turn off, my muscle and muscleExercise variables are going back to their default value. Here some code for you : @EnvironmentObject var dataManager: DataManager @Environment(\.modelContext) private var context @AppStorage("savedGroupName") private var savedGroupName: String = "" @AppStorage("savedExerciceName") private var savedExerciceName: String = "" @State var groupName: String = "À choisir" @State var ExerciceChoose: String = "À choisir" I use my variables here : HStack { Text("Muscle:") Spacer() NavigationLink(destination: MusclesView()) { Text(savedGroupName.isEmpty ? "À choisir" : savedGroupName) } .buttonStyle(PlainButtonStyle()) } .onAppear { savedGroupName = groupName } HStack { Text("Exercise:") Spacer() NavigationLink(destination: MuscleExercicesView(groupName: groupName, ExerciceChoose: ExerciceChoose)) { Text(savedExerciceName.isEmpty ? "À choisir" : savedExerciceName) } .onAppear { savedExerciceName = ExerciceChoose } .buttonStyle(PlainButtonStyle()) } The value of my muscle variable is taking in an other view : struct MusclesView: View { let muscleGroup = ExerciceData.muscleGroups var body: some View { NavigationStack { List(muscleGroup, id: \.name) { group in NavigationLink(destination: MuscleExercicesView(groupName: group.name, ExerciceChoose: "À choisir")) { Text(group.name) } } } } } #Preview { MusclesView() } and the value of the exerciseMuscle variable is also taking in an other view : ```import SwiftUI struct MuscleExercicesView: View { let exerciceGroup = ExerciceData.muscleGroups @State var groupName: String @State var ExerciceChoose: String var body: some View { if let group = ExerciceData.muscleGroups.first(where: { $0.name == groupName }) { List(group.exercices, id: \.id) { exercice in NavigationLink(exercice.name, destination: CurrentInformationsView(groupName: groupName, ExerciceChoose: exercice.name)) } /*.onTapGesture { print("Selected exercise: \(ExerciceChoose) for muscle group: \(groupName)") }*/ .navigationTitle(Text("Exercices pour \(groupName)")) } else { Text("Aucun exercice trouvé pour \(groupName)") .navigationTitle(Text("Erreur")) } } } #Preview { MuscleExercicesView(groupName: "Pectoraux", ExerciceChoose: "À choisir") } I tried many things (like userDefault, put my values in an array to save it etc..) to keep my variables with the same value during the session but nothing works. I wish I could have some help from you guys. Have a good day ! Cyrille
0
0
159
3w