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

SwiftUI Documentation

Post

Replies

Boosts

Views

Activity

Live Activity Text Style Issue in iOS Simulator's lock screen (iOS 17.2)
Environment: iOS Version: 17.2 iOS Simulator Version: 17.2 Xcode Version: 15.2 Device: iPhone 15 Pro Max App Target Version: iOS 17.2 Preconditions: App with Live Activity feature is installed. Device/Simulator is running iOS 17.2. Steps to Reproduce: Start the app and initiate a Live Activity with text styled as .timer. Lock the device screen or switch to the lock screen view in the iOS Simulator. Observe the Live Activity on the lock screen, noting the text style. Unlock the device. This time noting the .timer changed its style. The text style of the Live Activity remains consistent both on the lock screen and after unlocking the device, maintaining its .timer style throughout its lifecycle. Frequency: Occurs every time the steps are reproduced.
4
2
509
Jan ’24
QLPreviewController with SwiftUI
I'm having a problem where any buttons won't be shown when displaying a QLPreviewController with swift. With .quickLookPreview() these buttons are shown, including share, done, annotation etcetera. The buttons are not shown when using QLPreviewController with SwiftUI, however if used with other UIKit they are shown. How to fix this? I'm not really looking forward in implementing all of the annotation functions and other QuickLook capabilities again. The ultimate goal of mine is to allow annotation and other pdf editing with the ability to save the file via the Done button, but on .quickLookPreview() the Done button displays "Save to files" and "Discard" and on QLPreviewController the button is not shown. The issue has been addressed on several forums, yet a solution has not been found. Reproducement in nutshell: new QLPreviewController conforming to UIViewControllerRepresentable display the QLPreviewController in SwiftUI view Thanks.
0
0
74
4d
SwiftData Model deletion works unstable
Hi, I believe this question belongs here instead of Stack Overflow as SwiftUI + SwiftData is too new. I am using Model Context from a static Helper class: Class Helper { static let shared = Helper() var modelContext: ModelContext? } call to insert data on the 1st screen: Helper.shared.modelContext?.insert(item) Query Model declaration on the 1st screen: @Query private var products: [ProductModel] also autoSave turned to false: .onAppear{ Helper.shared.modelContext?.autosaveEnabled = false } periodically update data via a standard Timer object: for item in products { item.price = 500 } SwiftData works just fine in this 1st screen, but when we try to delete the Model and move on to next screen, we found out memory of the previous screen Model (ProductModel) in this case is still persisted and keep increasing! Eventually causing hang in the 2nd screen. Model deletion code in onDisappear of the 1st screen: .onDisappear{ try? Helper.shared.modelContext?.delete(model: ProductModel.self) try? Helper.shared.modelContext?.save() } Any clue where we might be wrong? Thanks
0
0
67
5d
Swift Charts performance when displaying many data points
I'm currently evaluating Swift Charts to use in my macOS app, where I need to (potentially) display a few millions of data points, ideally all of them at one time. I want to give users the possibility to zoom in & out, so the entire range of values could be displayed at one moment. However, starting at around 20K data points (on my computer), the Chart takes a little bit to set up, but the window resizing is laggy. The performance seems to decrease linearly (?), when dealing with 100K data points you can barely resize the window and the Chart setup/creation is noticeable enough. Dealing with 500K data points is out of the question, the app is pretty much not useable. So I'm wondering if anybody else had a similar issue and what can be done? Is there any "magic" Swift Charts setting that could improve the performance? I have a "data decimation" algorithm, and given no choice I will use it, but somehow I was hoping for Swift Charts to gracefully handle at least 100K data points (there are other libs which do this!). Also, limiting the displayed data range is out of the question for my case, this is a crucial feature of the app. Here's the code that I'm using, but it's the most basic one: struct DataPoint: Identifiable { var id: Double { Double(xValue) } let xValue: Int let yValue: Double } let dataPoints: [DataPoint] = (0..<100_000).map { DataPoint(xValue: $0, yValue: Double($0)) } struct MyChart: View { var body: some View { Chart(dataPoints) { dataPoint in PointMark(x: .value("Index", dataPoint.xValue), y: .value("Y Value", dataPoint.yValue)) } } } Some additional info, if it helps: The Chart is included in a AppKit window via NSHostingController (in my sample project the window contains nothing but the chart) The computer is a MacBook Pro, 2019 and is running macOS 10.14
2
1
624
Oct ’23
iOS 17 - TextField color does not changes with state is updated
Hi! I find this code does not work as expected on iOS 17 simulator and device. It was working correctly with iOS 16: struct ContentView: View { @State private var numberText = "" var color: Color { let result = (Int(numberText) ?? 0) <= 0 if result { return .black } return .red } var body: some View { VStack { TextField("Enter a number", text: $numberText) .font(.title) .foregroundStyle( color ) Text("Font color will turn red if number > 0") .foregroundColor(.gray) } .padding() } } I tried a workaround and it works: struct ContentView: View { @State private var numberText = "" @State private var color = Color.black func updateColor() ->Color { let result = (Int(numberText) ?? 0) <= 0 if result { return .black } return .red } var body: some View { VStack { TextField("Enter a number", text: $numberText) .font(.title) .foregroundStyle( color ) .onChange(of:numberText) { color = updateColor() } Text("Font color will turn red if number > 0") .foregroundColor(.gray) } .padding() } }
5
1
887
Oct ’23
How to debug this?
I have a small app written in SwiftUI and using SwiftData. It's been performing well for around a month but now suddenly I am getting the error below. No changes have been made to the models in use. Looking at the error it appears to be when SwiftData commits data but how can I tell what it is trying (and failing) to commit? Some way of knowing the model being referenced would help me diagnose this further. The error occurs at random intervals, though I'm guessing that's partly reflected by the design of SwiftData? [error] error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x60000376af40> , -[__NSDictionaryM UTF8String]: unrecognized selector sent to instance 0x60000022adc0 with userInfo of (null) CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x60000376af40> , -[__NSDictionaryM UTF8String]: unrecognized selector sent to instance 0x60000022adc0 with userInfo of (null) *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryM UTF8String]: unrecognized selector sent to instance 0x60000022adc0' *** First throw call stack: ( 0 CoreFoundation 0x00000001804ae138 __exceptionPreprocess + 172 1 libobjc.A.dylib 0x0000000180087db4 objc_exception_throw + 56 2 CoreFoundation 0x00000001804c2f88 +[NSObject(NSObject) instanceMethodSignatureForSelector:] + 0 3 CoreFoundation 0x00000001804b2288 forwarding + 1280 4 CoreFoundation 0x00000001804b45ac _CF_forwarding_prep_0 + 92 5 CoreData 0x0000000186537b90 -[NSSQLiteConnection execute] + 1104 6 CoreData 0x0000000186534b58 -[NSSQLiteConnection updateRow:forRequestContext:] + 1848 7 CoreData 0x0000000186634378 _executeSaveChangesRequest + 2216 8 CoreData 0x000 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryM UTF8String]: unrecognized selector sent to instance 0x60000022adc0' *** First throw call stack: ( 0 CoreFoundation 0x00000001804ae138 __exceptionPreprocess + 172 1 libobjc.A.dylib 0x0000000180087db4 objc_exception_throw + 56 2 CoreFoundation 0x00000001804c2f88 +[NSObject(NSObject) instanceMethodSignatureForSelector:] + 0 3 CoreFoundation 0x00000001804b2288 forwarding + 1280 4 CoreFoundation 0x00000001804b45ac _CF_forwarding_prep_0 + 92 5 CoreData 0x0000000186537b90 -[NSSQLiteConnection execute] + 1104 6 CoreData 0x0000000186534b58 -[NSSQLiteConnection updateRow:forRequestContext:] + 1848 7 CoreData 0x0000000186634378 _executeSaveChangesRequest + 2216 8 CoreData 0x000000018661e5e8 -[NSSQLSaveChangesRequestContext executeRequestCore:] + 28 9 CoreData 0x000000018641b28c -[NSSQLStoreRequestContext executeRequestUsingConnection:] + 248 10 CoreData 0x00000001864b4df4 __52-[NSSQLDefaultConnectionManager handleStoreRequest:]_block_invoke + 56 11 CoreData 0x000000018652d790 __37-[NSSQLiteConnection performAndWait:]_block_invoke + 40 12 libdispatch.dylib 0x00000001016e573c _dispatch_client_callout + 16 13 libdispatch.dylib 0x00000001016f648c _dispatch_lane_barrier_sync_invoke_and_complete + 144 14 CoreData 0x000000018652d248 -[NSSQLiteConnection performAndWait:] + 132 15 CoreData 0x00000001864b4d14 -[NSSQLDefaultConnectionManager handleStoreRequest:] + 204 16 CoreData 0x00000001865f29f4 -[NSSQLCoreDispatchManager routeStoreRequest:] + 220 17 CoreData 0x00000001864fa280 -[NSSQLCore dispatchRequest:withRetries:] + 168 18 CoreData 0x00000001864fc9e4 -[NSSQLCore executeRequest:withContext:error:] + 2116 19 CoreData 0x00000001864c6a84 __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke.383 + 9184 20 CoreData 0x00000001864bbac4 -[NSPersistentStoreCoordinator _routeHeavyweightBlock:] + 216 21 CoreData 0x00000001864c3ec8 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1100 22 CoreData 0x000000018647c8f8 -[NSManagedObjectContext save:] + 968 23 SwiftData 0x00000001cb408450 _swift_destroy_boxed_opaque_existential_0Tm + 50180 24 SwiftData 0x00000001cb4168d4 block_destroy_helper + 132 25 CoreData 0x00000001863cfec4 $sxs5Error_pIgrzo_xsAA_pIegrzo_lTR + 20 26 CoreData 0x00000001863d2198 $sxs5Error_pIgrzo_xsAA_pIegrzo_lTRTA + 20 27 CoreData 0x00000001863d1c8c $sSo22NSManagedObjectContextC8CoreDataE30_rethrowsHelper_performAndWait33_A0F63BA25A751D403694B89F4AD0A24ELL2fn7execute6rescuexyyyXEXE_xyKXExs5Error_pKXEtKlFyxyKcXEfU_yyXEfU + 108 28 CoreData 0x00000001863d04a4 $sIg_Ieg_TR + 20 29 CoreData 0x00000001863d04f4 $sIeg_IyB_TR + 20 30 CoreData 0x000000018648584c developerSubmittedBlockToNSManagedObjectContextPerform + 156 31 CoreData 0x0000000186485728 -[NSManagedObjectContext performBlockAndWait:] + 212 32 CoreData 0x00000001863d203c $sSo22NSManagedObjectContextC8CoreDataE14performAndWaityxxyKXEKlF + 352 33 SwiftData 0x00000001cb407b60 __swift_destroy_boxed_opaque_existential_0Tm + 47892 34 SwiftData 0x00000001cb4077a8 __swift_destroy_boxed_opaque_existential_0Tm + 46940 35 SwiftData 0x00000001cb40789c __swift_destroy_boxed_opaque_existential_0Tm + 47184 36 Foundation 0x0000000180e12924 __NSFireTimer + 56 37 CoreFoundation 0x000000018040f588 CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION + 28 Suggestions for narrowing down the cause gratefully accepted :-)
6
0
337
May ’24
How to resolve SwiftUI.DynamicProperty on MainActor compiler warning on 6.0?
Hi! I'm running into a warning from a SwiftUI.DynamicProperty on a 6.0 development build (swift-6.0-DEVELOPMENT-SNAPSHOT-2024-03-26-a). I am attempting to build a type (conforming to DynamicProperty) that should also be MainActor. This type with also need a custom update function. Here is a simple custom wrapper (handwaving over the orthogonal missing pieces) that shows the warning: import SwiftUI @MainActor struct MainProperty: DynamicProperty { // Main actor-isolated instance method 'update()' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode @MainActor func update() { } } Is there anything I can do about that warning? Does the warning correctly imply that this will be a legit compiler error when 6.0 ships? I can find (at least) two examples of types adopting DynamicProperty from Apple that are also MainActor: FetchRequest and SectionedFetchRequest. What is confusing is that both FetchRequest^1 and SectionedFetchRequest^2 explicitly declare their update method to be MainActor. Is there anything missing from my Wrapper declaration that can get me what I'm looking for? Any more advice about that? Thanks!
3
0
418
Apr ’24
Live Activity compact timers
The Human Interface Guidelines for Live Activities provide several examples of compact presentations that have a timer counting down formatted like "3min" or "3m", similar to the timers in the Clock app. Such examples can be found in this Stack Overflow question: https://stackoverflow.com/questions/77551496/is-it-possible-to-make-an-only-minutes-1m-countdown-in-a-live-activity A Timer initialized with init(timerInterval:pauseTime:countsDown:showsHours:) has provided a live countdown timer in widgets and live activities, but the formatting is limited. And since live activities come with limitations that prevent us from using Timers, there's no real way to implement this kind of thing ourselves. What is Apple's official guidance for implementing this kind of timer for the compact presentation?
3
2
283
Jun ’24
Why can't SwiftUI state be changed in the middle of view updates?
I have arrived at a certain architectural solution for my SwiftUI code which is helped by, in certain situations, modifying the state while the body is being evaluated. Of course, I am always open to realizing that a given solution may be creating difficulties precisely because it is fundamentally ill-advised. However, in this post I won't attempt to explain the details of my architecture or justify my reasoning regarding wanting to change the state in the middle of a view update. I just want to ask, why exactly is it prohibited? Is it not rather like normal recursion, which can of course produce infinite loops if done wrong but which is perfectly logically sound as long as the recursing function eventually stabilizes?
5
0
153
1w
Slider .rotationEffect broken in MacOS 14.5
In a SwiftUI app for MacOS, vertical sliders that I'd created using a rotationEffect of 90° disappeared when I upgraded to Sonoma 14.5 (23F79). With rotations less than 90°, the slider is still visible, but its button is enlarged, growing in size as the rotation angle approaches 90°. Note that the sliders still work, even when rotated by 90° and invisible! The screenshot and code below demonstrates the problem, which did not exist in MacOS 14.2.1 struct ContentView: View { @State var speed = CGFloat(1) var body: some View { HStack { let angle: [Double] = [0, 45, 80, 85, 90] ZStack { ForEach(0...4, id: \.self) { i in ZStack () { Rectangle() Slider(value: $speed, in: 0...10 ) } .frame(width: 100, height: 10) .rotationEffect(.degrees(angle[i])) .offset(x: CGFloat(i * 100) - 180) } } } .padding() .frame(width: 600, height: 200) } } #Preview { ContentView() }
5
1
175
Jun ’24
Create Window backed by NSPanel in SwiftUI app
Is it possible to create a custom scene that would provide a Window instance backed by NSPanel on macOS instead of regular NSWindow? Ideally, I would have the following in my app: @main struct MaccyApp: App { var body: some Scene { Panel("Maccy", id: "org.p0deje.Maccy") { // similar to Window(...) ContentView() } } } where Panel would implement a custom logic to present itself so the views could access scenePhase, openWindow and dismiss and other common environment values. I know there is a way to access window and customize it by implement an NSViewRepresentable view with makeNSView(context:), however there is no way to replace the used window with a different implementation class such as NSPanel.
0
0
61
5d
arrowEdge of popoverTip not working anymore on iOS 17.1
In iOS 17.1 (and 17.2 beta), the arrowEdge parameter of the SwiftUI popoverTip doesn't work anymore. This code button .popoverTip(tip, arrowEdge: .bottom) looks like this on iOS 17.0 and like this on 17.1 and up. I checked permittedArrowDirections of the corresponding UIPopoverPresentationController (via the Memory Graph): It's .down on iOS 17.0 and .any (the default) on 17.1. It seems the parameter of popoverTip is not properly propagated to the popover controller anymore.
2
1
700
Nov ’23
SwiftUI Map Annotation Coordinate Animation
Hi, I have a SwiftUI Map with a set of three annotations. These annotations move around, and I would like to animate their movement from one coordinate to another, but I'm not finding a way to do that. I've tried using withAnimation { } when setting my array of Identifiable models that back the Annotations, and I've tried adding the .animation(.default, annotationModels) modifier to my Map object (where annotationModels is the array that backs my Annotations). The animation modifier doesn't work on Annotation structs, and it doesn't work if I add the animation modifier within the Annotation's view either. Does anyone have any suggestions on how I might be able to animate the coordinates of annotations using a SwiftUI Map? Does the problem have to do with the fact that I have an array of these annotations?
0
0
117
6d
Swift Chart Zoom/Magnification/Pinch Gesture
Is there any approach or sample code available to use these APIs: .chartScrollableAxes(.horizontal) .chartScrollPosition(x: ...) .chartScrollPosition(initialX: ...) .chartScrollTargetBehavior(...) .chartXVisibleDomain(length: ...) Plus a gesture recognised or Pinch or Magnification to create a Swift Chart with an X axis that can be zoomed in or out with a pinch gesture? And when zoomed in at any level above 0, the chart can then be scrolled left to right along the X axis. I've had success using .chartScrollableAxes with .chartXSelection in parallel, so would also like to keep the ability to select X values too.
0
0
124
6d
Can't figure out why Toolbar is not conforming to view
ToolbarItem in group is not conforming to view for some reason, here's my code: var body: some View { NavigationStack { Form { TextField("Company Name", text: $companyName) TextField("Role", text: $role) TextField("Location", text: $location) TextField("Yearly Salary", value: $yearlySalary, format: .currency(code: "USD")) .keyboardType(.decimalPad) } .navigationTitle("Add Application") .navigationBarTitleDisplayMode(.large) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("back") { dismiss() } } ToolbarItem(placement: .navigationBarTrailing) { Button("Save") { let appdata = ApplicationData( companyName: companyName, role: role, location: location, yearlySalary: yearlySalary, dateApplied: dateApplied, notes: notes) // Save the application data dismiss() } } } } } The error reads: Static method 'buildExpression' requires that 'ToolbarItem<(), Button>' conform to 'View' I'm trying to change it up but I can't get past this error for some reason
2
0
140
1w
[VisionOS] TextEditor does not respect .autocorrectionDisabled
Hello everyone, I wanted to double check with the UI Framework team to see if there's a mistake in my code or if there's some sort of regression. My goal is to have a user input text without any automatic modification of said text, namely remove auto-capitalization and auto-correct. // // ContentView.swift // TextInputTest // import SwiftUI struct ContentView: View { @State var text: String = "Enter some text here!" var body: some View { VStack { TextEditor(text: $text) .autocorrectionDisabled(true) .textInputAutocapitalization(.never) .font(Font.custom("SF Mono", size: 30)) .monospaced() .padding(20) } .padding() } } However, when typing the following: "This is a sentence" followed by a few spaces, a dot will automatically be inserted, making the string become: "This is a sentence.". Reproduced on: VisionOS 2.0 beta 3 (22N5277g)
1
0
111
6d
UIRefresh not working for my project?
So for my project it's a SwiftUI Project however if I Add '@objc' to expose this instance method to Objective-C it doesn't want it for some reason and the other error code is Argument of '#selector' refers to instance method 'refreshWebView' that is not exposed to Objective-C mainly this is the error I need to fix thanks in advance this code is what's giving me the error refreshControl.addTarget(self, action: #selector(refreshWebView(_:)), for: UIControl.Event.valueChanged) this is for a pull to refresh the page
3
0
150
6d
[VisionOS] .onDelete gesture not triggered for mouse
I found a regression in Apple Vision OS 2.0 beta 3 (22N5277g). Previously, it was possible to trigger the .onDelete swipe gesture on a List/ForEach with a virtual mouse (i.e. remote desktop), however this is no longer possible (a finger pinch still works). Sample code to reproduce the issue: // // ContentView.swift // TextInputTest // import SwiftUI struct ListElement: Identifiable { let id = UUID() let content: String } struct ContentView: View { @State var list = [ ListElement(content: "a"), ListElement(content: "b"), ListElement(content: "c") ] var body: some View { List { ForEach(list) { element in Text(element.content) } .onDelete { _ in // No-op. } } } }
0
0
90
6d
SwiftUI view is not updated properly
Task: A child view should show depending on a boolean flag the corresponding view. The flag is calculated from a model which is given by parent view. Problem: The flag is false in init, which is correct. However in body it's true, which is incorrect. Why value in body isn't consistent to init? Is there a race condition? The child view's is rendered thrice, that's another issue, but flag is in init and body as described before. Parent view looks like this: struct ParentView: View { private var groupedItems: [GroupedItems] = [] init(items: [Item]) { Dictionary(grouping: items) { $0.category.name } .forEach { let groupedItems = GroupedItems(categoryName: $0.key, items: $0.value) self.groupedItems.append(groupedItems) } } var body: some View { ChildView(groupedItems) } } Child view looks like this: struct ChildView: View { @State private var showItems: Bool init(_ groupedItems: GroupedItems) { self._showItems = State(initialValue: !groupedItems.completed) } var body: some View { if showItems { AView() } else { BView() } } } Model looks like this: @Model final class Item: Identifiable { @Attribute(.unique) public var id: String public var name: String public var completed = false } struct GroupedItems { var categoryName: String var items: [Item] var completed: Bool { items.filter { !$0.completed }.isEmpty } }
3
0
164
1w