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

Posts under SwiftUI tag

200 Posts

Post

Replies

Boosts

Views

Activity

Food Truck Sample animation issue from Table Component
Hi! I'm seeing some weird animation issues building the Food Truck sample application.^1 I'm running from macOS 15.4 and Xcode 16.3. I'm building the Food Truck application for macOS. I'm not focusing on iOS for now. The FoodTruckModel adds new Order values with an animation: // FoodTruckModel.swift withAnimation(.spring(response: 0.4, dampingFraction: 1)) { self.orders.append(orderGenerator.generateOrder(number: orders.count + 1, date: .now, generator: &generator)) } This then animates the OrdersTable when new Order values are added. Here is a small change to OrdersTable: // OrdersTable.swift - @State private var sortOrder = [KeyPathComparator(\Order.status, order: .reverse)] + @State private var sortOrder = [KeyPathComparator(\Order.creationDate, order: .reverse)] Running the app now inserts new Order values at the top. The problem is I seem to be seeing some weird animation issues here. It seems that as soon as the new Order comes in there is some kind of weird glitch where it appears as if part the animation is coming from the side instead of down from the top: What's then more weird is that if I seem to affect the state of the Table in any way then the next Order comes in with perfect animation. Scrolling the Table fixes the animation. Changing the creationData sort order from reverse to forward and back to reverse fixes the animation. Any ideas? Is there something about how the Food Truck product is built that would cause this to happen? Is this an underlying issue in the SwiftUI infra?
0
0
49
Apr ’25
Navbar buttons disappear in NavigationSplitView's sidebar when changing apps
We recently migrated our app to use NavigationSplitView on iPad with a sidebar and detail setup, and we got reports that the navigation buttons on the sidebar disappear when returning to our app after using a different app. I reproduced the issue from a new empty project with the following code (issue tested on iOS 17.4 and iOS 18.3, was not able to reproduce on iOS 16.4): import SwiftUI @main struct TestApp: App { var body: some Scene { WindowGroup { NavigationSplitView { Text("sidebar") .toolbar { ToolbarItem(placement: .topBarLeading) { Button(action: {}) { Image(systemName: "square.and.arrow.down") } } ToolbarItem(placement: .topBarTrailing) { Button(action: {}) { Image(systemName: "square.and.arrow.up") } } } } detail: { Text("detail") .toolbar { ToolbarItem(placement: .topBarLeading) { Button(action: {}) { Image(systemName: "eraser") } } ToolbarItem(placement: .topBarTrailing) { Button(action: {}) { Image(systemName: "pencil") } } } } } } } Please check the following GIF for the simple steps, notice how the navbar buttons in the detail view do not disappear: Here's the console output, it shows that the constraints break internally:
0
0
82
Apr ’25
Accessing an actor's isolated state from within a SwiftUI view
I'm trying to understand a design pattern for accessing the isolated state held in an actor type from within a SwiftUI view. Take this naive code: actor Model: ObservableObject { @Published var num: Int = 0 func updateNumber(_ newNum: Int) { self.num = newNum } } struct ContentView: View { @StateObject var model = Model() var body: some View { Text("\(model.num)") // <-- Compiler error: Actor-isolated property 'num' can not be referenced from the main actor Button("Update number") { Task.detached() { await model.updateNumber(1) } } } } Understandably I get the compiler error Actor-isolated property 'num' can not be referenced from the main actor when I try and access the isolated value. Yet I can't understand how to display this data in a view. I wonder if I need a ViewModel that observes the actor, and updates itself on the main thread, but get compile time error Actor-isolated property '$num' can not be referenced from a non-isolated context. class ViewModel: ObservableObject { let model: Model @Published var num: Int let cancellable: AnyCancellable init() { let model = Model() self.model = model self.num = 0 self.cancellable = model.$num // <-- compile time error `Actor-isolated property '$num' can not be referenced from a non-isolated context` .receive(on: DispatchQueue.main) .sink { self.num = $0 } } } Secondly, imagine if this code did compile, then I would get another error when clicking the button that the interface is not being updated on the main thread...again I'm not sure how to effect this from within the actor?
3
2
9.6k
Apr ’25
After updating to Xcode 16.3, getting the error - Symbol not found: ___cxa_current_primary_exception
It didn't happen with Xcode 16.2 that I used before, but after updating to 16.3, when I build the app, the following error is output to the console and the app doesn't run. dyld[2150]: Symbol not found: ___cxa_current_primary_exception Referenced from: <6B00A4F2-B208-3FDB-BA38-B7095AF0034A> /private/var/containers/Bundle/Application/B590DB18-9C66-4C9E-8330-104943419E60/Mubeat DEV.app/Mubeat DEV.debug.dylib Expected in: <7F51CB08-A0CA-386E-BB62-4B8BFB0CED9F> /usr/lib/libc++.1.dylib Symbol not found: ___cxa_current_primary_exception Referenced from: <6B00A4F2-B208-3FDB-BA38-B7095AF0034A> /private/var/containers/Bundle/Application/B590DB18-9C66-4C9E-8330-104943419E60/Mubeat DEV.app/Mubeat DEV.debug.dylib Expected in: <7F51CB08-A0CA-386E-BB62-4B8BFB0CED9F> /usr/lib/libc++.1.dylib dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib After looking for another solution, I found a way to remove the -Objc option in Other Linker Flags, but this method only works on iOS 18.4 and doesn't work on other versions. Is there another solution?
5
4
1.9k
Apr ’25
Trying to drag a modelEntity inside an Immersive space
Goal : Drag a sphere across the room and track it's position Problem: The gesture seems to have no effect on the sphere ModelEntity. I don't know how to properly attach the gesture to the ModelEntity. Any help is great. Thank you import SwiftUI import Foundation import UIKit @main struct testApp: App { @State var immersionStyle:ImmersionStyle = .mixed var body: some Scene { ImmersiveSpace { ContentView() } .immersionStyle(selection: $immersionStyle, in: .mixed, .full, .progressive) } } struct ContentView: View { @State private var lastPosition: SIMD3? = nil @State var subscription: EventSubscription? @State private var isDragging: Bool = false var sphere: ModelEntity { let mesh = MeshResource.generateSphere(radius: 0.05) let material = SimpleMaterial(color: .blue, isMetallic: false) let entity = ModelEntity(mesh: mesh, materials: [material]) entity.generateCollisionShapes(recursive: true) return entity } var drag: some Gesture { DragGesture() .onChanged { _ in self.isDragging = true } .onEnded { _ in self.isDragging = false } } var body: some View { RealityView { content in //1. Anchor Entity let anchor = AnchorEntity(world: SIMD3<Float>(0, 0, -1)) let ball = sphere //2. add anchor to sphere anchor.addChild(ball) content.add(anchor) subscription = content.subscribe(to: SceneEvents.Update.self) { event in let currentPosition = ball.position(relativeTo: nil) if let last = lastPosition, last != currentPosition { print("Sphere moved from \(last) to \(currentPosition)") } lastPosition = currentPosition } } .gesture(drag) } }
1
0
46
Apr ’25
Is there a global Alert View in SwiftUI?
I am writing a SwiftUI based app, and errors can occur anywhere. I've got a function that logs the error. But it would be nice to be able to call an Alert Msg, no matter where I am, then gracefully exits the app. Sure I can right the alert into every view, but that seems ridiculously unnecessary. Am I missing something?
2
0
94
Apr ’25
TipViewStyle layout broken in iOS 18.4 – Tip message gets truncated
Hi everyone, I’m using a custom TipViewStyle to modify the background and slightly adjust the layout of the Tips in my app. Everything looked great until iOS 18.4. Since updating, the layout is being compressed, and the message inside the Tip is getting truncated. Here’s a screenshot of how it looks on iOS 18.4 (truncated message) and another showing how it used to look before iOS 18.4 (correct layout). Here is the relevant code for the custom style: struct CustomTipViewStyle: TipViewStyle { func makeBody(configuration: Configuration) -> some View { VStack(alignment: .leading, spacing: 4) { HStack { configuration.title? .font(.headline) .foregroundColor(.daBackground) Spacer() Button(action: { configuration.tip.invalidate(reason: .tipClosed) }) { Image(systemName: "xmark") .foregroundColor(.daBackground.opacity(0.3)) } } VStack(alignment: .leading, spacing: 8.0) { configuration.message? .font(.subheadline) .foregroundColor(.daBackground.opacity(0.8)) Divider().background(.daBackground.opacity(0.3)) ForEach(configuration.actions) { action in HStack { Spacer() Button(action: action.handler) { action.label() .foregroundStyle(.accent) .font(.system(size: 18, weight: .bold)) } } } } } .padding() .background(Color.daBlack) } } Has anyone else experienced this issue with TipViewStyle in iOS 18.4? Any workarounds or solutions would be appreciated! Thanks in advance!
1
1
76
Apr ’25
How do I maintain a stable scroll position when inserting items above in a ScrollView?
As the title says, I am not sure how to properly build an inverted ScrollView where I can safely insert items above my data ("prepend") without everything jumping around. My current code is essentially this: @State private var scrollPosition = ScrollPosition(idType: Message.ID.self) private func onMessageDidScrollIntoView(_ id: Message.ID) { let indexOfVisibleMessage = /* ... */ if indexOfVisibleMessage < 10 { fetchOlderMessages() // ^ this updates my ViewModel `messages` } } var body: some View { ScrollView { LazyVStack { ForEach(messages) { message in MessageCell(message) } }.scrollTargetLayout() } .defaultScrollAnchor(.bottom) .scrollPosition($scrollPosition) .onChange(of: scrollPosition) { oldValue, newValue in guard let visibleMessageId = scrollPosition.viewID(type: Message.ID.self) else { return } onMessageDidScrollIntoView(visibleMessageId) } } ..so if the user scrolls up to the oldest 10 messages, I start loading more and insert them at the top. The problem with this is that the ScrollView now jumps when new messages are inserted. This is because the ScrollView maintains it's Y position, but the content size changes since we are adding new items "above". I tried to play around with a few suggestions I found on StackOverflow, namely; Inverting the ScrollView (.scaleEffect(y: -1) on the ScrollView and then again on the MessageCell to counter it): This somehow jumped the x position of the ScrollView and completely breaks .contextMenu. Playing around with .onScrollGeometryChange to update scrollPosition.scrollTo(y:) when it's contentSize changes: This just didn't work and stopped the user scroll gesture/interaction. Setting scrollPosition to the Message.ID I want to keep stable before doing an update: This didn't do anything. But nothing actually worked for the reasons described above. How do you actually build these UIs in SwiftUI? I think an inverted ScrollView is quite a common UI, and obviously data has to be loaded lazily.
0
1
45
Apr ’25
Should i set window.isReleasedWhenClosed to true or leave it to default?
Hi, In mac os swift ui application when i set window.isReleasedWhenClosed and when i close the window the app is getting crashed with exc_bad_access. but when i leave it to default value the app is not crashing. for some windows setting window.isReleasedWhenClosed to true is woking properly when closing the windows. But for some windows it is crashing. If i dont set it to true the window is not removed from NSApplication.shared.windows sometimes. I am confused about setting isReleasedWhenClosed to true Could someone calrify on this please. thank in advance.
2
0
47
Apr ’25
I think I found a bug in SwiftUI on macOS 15.4 that crashes apps
We've been receiving crash reports for our app from users that have upgraded to macOS 15.4. I have upgraded my developer machine and immediately was able to reproduce the crash. I was able to create a minimal reproducible scenario. The following view crashes the app when sheet is presented with this trace: The window has been marked as needing another Update Constraints in Window pass, but it has already had more Update Constraints in Window passes than there are views in the window. <_TtC7SwiftUIP33_7B5508BFB2B0CAF1E28E206F2014E66B23SheetPresentationWindow: 0x1111074c0> 0x9bd (2493) {{0, 0}, {100, 108}} en ( 0 CoreFoundation 0x000000018bdfddf0 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000018b8c2b60 objc_exception_throw + 88 2 CoreFoundation 0x000000018bdfdce0 +[NSException exceptionWithName:reason:userInfo:] + 0 3 AppKit 0x000000019043d394 -[NSWindow(NSDisplayCycle) _postWindowNeedsUpdateConstraints] + 1788 4 AppKit 0x000000018f9f8c08 -[NSView _informContainerThatSubviewsNeedUpdateConstraints] + 64 5 AppKit 0x000000018f9f8b8c -[NSView setNeedsUpdateConstraints:] + 468 6 SwiftUI 0x00000001bc0e5110 $s7SwiftUI13NSHostingViewC14setNeedsUpdate33_32B6F54841135BB466A5C1362EB89D05LLyyF + 80 7 SwiftUI 0x00000001bc101f28 $s7SwiftUI13NSHostingViewC13requestUpdate5afterySd_tF + 616 Conditions that are important: accessing a publishable property inside the sheet .sheet() on a component that is wrapped in another (VStack is required in the example provided) being used inside NavigationSplitView Presents of @Environment(\.openURL. Doesn't have to be used, simply present on the view. struct ContentView: View { @Environment(\.openURL) private var open @State var who = "world" @State var shown = false var body: some View { NavigationSplitView(sidebar: { Text("Hello, world") }, detail: { VStack(spacing: 20) { Button("Kill me pls") { shown = true } .frame(width: 110, height: 110) .sheet(isPresented: $shown) { VStack { HStack() { Text("Hello, \(who)!") } } .presentationBackground(.thinMaterial) } } }) } }
2
0
98
Apr ’25
Text is truncated with certain font sizes on iOS 17+, but not on iOS 16
’m experiencing an issue where a Text view is unexpectedly truncated with certain font sizes (e.g., .body) on iOS 17 and later. This does not occur on iOS 16. I’ve applied .fixedSize(horizontal: false, vertical: true) to allow the text to grow vertically, but it still doesn’t show the entire content. Depending on the text content or font size, it sometimes works, but not always. How can I ensure the full text is displayed correctly on iOS 17+? Here is a minimal reproducible SwiftUI example: let sampleText1 = """ これはサンプルのテキストです、 ・箇条書き1 ・箇条書き2 であかさたなクロを送り、 アアを『ああああいいいい』フライパンに入れ、あかさたなです😋 """ let sampleText2 = """ 【旬|最高級】北海道産 生サンマ 釜飯 ----- Aaa iii uuu """ struct ContentView: View { var body: some View { ScrollView { VStack(alignment: .leading, spacing: 10) { HStack { MessageTextView(text: sampleText1) .layoutPriority(100) Spacer() } HStack { MessageTextView(text: sampleText2) .layoutPriority(100) Spacer() } } } } } struct MessageTextView: View { var text: String var body: some View { Text(text) .fixedSize(horizontal: false, vertical: true) .font(.body) .padding(.leading, 16) .padding(.trailing, 16) .padding(.top, 8) .padding(.bottom, 8) } } img1 img2
4
0
125
Apr ’25
Question about BGAppRefreshTask approach for medication scheduling app
I'm developing a medication scheduling app similar to Apple Health's Medications feature, and I'd like some input on my current approach to background tasks. In my app, when a user creates a medication, I generate ScheduledDose objects (with corresponding local notifications) for the next 2 weeks and save them to SwiftData. To ensure this 2-week window stays current, I've implemented a BGAppRefreshTask that runs daily to generate new doses as needed. My concern is whether BGAppRefreshTask is the appropriate mechanism for this purpose. Since I'm not making any network requests but rather generating and storing local data, I'm questioning if this is the right approach. I'm also wondering how Apple Health's Medications feature handles this kind of scheduling. Their app seems to maintain future doses regardless of app usage patterns. Has anyone implemented something similar or can suggest the best background execution API for this type of scenario? Thanks for any guidance you can provide.
2
0
116
Apr ’25
SwiftData and @Query to find all records for the current date of a multidatepicker (Set = [])
I’m trying to build a CRUD app using SwiftData, @Query model and multidatepicker. The data from a multidatepicker is stored or persists in SwiftData as Set = []. My current dilemma is how to use SwiftData and @Query model Predicate to find all records on the current date. I can’t find any SwiftData documentation or examples @Query using Set = []. My CRUD app should retrieve all records for the current date. Unfortunately, I don’t know the correct @Query model syntax for Set = [].
0
0
48
Apr ’25
Calling from Watchos
I am working with a watchOS app in SwiftUI, and I am using the following code to dial a phone number from the watch: var number = "123456789" if let telURL = URL(string: "tel:\(number)") { let wkExtension = WKExtension.shared() wkExtension.openSystemURL(telURL) } The issue is that when I try to dial a number starting with a * (asterisk) or # (hash), it doesn't work. When dialing a regular number, it works fine. Is there any way to get this to work?
1
0
87
Apr ’25
dropDestination does not work inside List
I've discovered an issue with using iOS 16's Transferable drag-and-drop APIs for SwiftUI. The dropDestination modifier does not work when applied to a subview of a List. This code below will not work, unless you replace the List with a VStack or any other container (which, of course, removes all list-specific rendering). The draggable modifier will still work and the item will drag, but the dropDestination view won't react to it and neither closure will be called. struct MyView: View { var body: some View { List { Section { Text("drag this title") .font(.largeTitle) .draggable("a title") } Section { Color.pink .frame(width: 400, height: 400) .dropDestination(for: String.self) { receivedTitles, location in true } isTargeted: { print($0) } } } } } Has anyone encountered this bug and perhaps found a workaround?
8
0
3.4k
Apr ’25
how to achieve "concave in" glass view look?
I have been trying to implement this look where a component looks "pushed in" but I could not find any resources regarding this effect. The closest I got was a combination of a RoundedRectangle and .glassBackgroundEffect(), but this makes the view look pushed out, instead of pushed in. I was wondering if this is achievable in SwiftUI level, or even in UIKit level.
1
0
90
Apr ’25
SwiftData "Auto Inserts" array into ModelContext
Definitely one of the stranger quirks of SwiftData I've come across. I have a ScriptView that shows Line entities related to a Production, and a TextEnterScriptView that’s presented in a sheet to input text. I’m noticing that every time I type in the TextEditor within TextEnterScriptView, a new Line shows up in ScriptView — even though I haven’t explicitly inserted it into the modelContext. I'm quite confused because even though I’m only assigning a new Line to a local @State array in TextEnterScriptView, every keystroke in the TextEditor causes a duplicate Line to appear in ScriptView. In other words, Why is SwiftData creating new Line entities every time I type in the TextEditor, even though I’m only assigning to a local @State array and not explicitly inserting them into the modelContext? Here is my minimal reproducible example: import SwiftData import SwiftUI @main struct testApp: App { var body: some Scene { WindowGroup { ContentView() .modelContainer(for: Line.self, isAutosaveEnabled: false) } } } struct ContentView: View { @Environment(\.modelContext) var modelContext @Query(sort: \Production.title) var productions: [Production] var body: some View { NavigationStack { List(productions) { production in NavigationLink(value: production) { Text(production.title) } } .navigationDestination(for: Production.self) { production in ScriptView(production: production) } .toolbar { Button("Add", systemImage: "plus") { let production = Production(title: "Test \(productions.count + 1)") modelContext.insert(production) do { try modelContext.save() } catch { print(error) } } } .navigationTitle("Productions") } } } struct ScriptView: View { @Query private var lines: [Line] let production: Production @State private var isShowingSheet: Bool = false var body: some View { List { ForEach(lines) { line in Text(line.content) } } .toolbar { Button("Show Sheet") { isShowingSheet.toggle() } } .sheet(isPresented: $isShowingSheet) { TextEnterScriptView(production: production) } } } struct TextEnterScriptView: View { @Environment(\.dismiss) var dismiss @State private var text = "" @State private var lines: [Line] = [] let production: Production var body: some View { NavigationStack { TextEditor(text: $text) .onChange(of: text, initial: false) { lines = [Line(content: "test line", production: production)] } .toolbar { Button("Done") { dismiss() } } } } } @Model class Production { @Attribute(.unique) var title: String @Relationship(deleteRule: .cascade, inverse: \Line.production) var lines: [Line] = [] init(title: String) { self.title = title } } @Model class Line { var content: String var production: Production? init(content: String, production: Production?) { self.content = content self.production = production } }
1
0
51
Apr ’25
Can SwiftUI on macOS create an NSComboButton?
Without resorting to NSViewRepresentable, is there a view or view modifier in SwiftUI that can create an NSComboButton on macOS? NSComboButton was introduced in macOS 13 and is (relatively) new to AppKit: Apple Developer - NSComboButton I only require support on macOS for this control. Note that this is not to be confused with NSComboBox, which is a completely different control.
1
0
77
Apr ’25
Can @Query and ModelActor co-exist? How?
Context: The SwiftUI @Query macro has an internal modelContext. The ModelActor also has a modelContext, from which the data should be read/written. Issue: When writing to @Model data fetched with @Query macro using a ModelActor, it will crash in the most not-obvious ways. Also, fetching @Model with ModelActor will result in errors in Swift 6 since @Model aren't sendable. Problem to Solve: - How to write a good amount of data to SwiftData/CoreData without blocking the UI thread? Would the recommendation from the Apple team be that a large amount of data should be read/written with ModelActor and a small amount should be done with the @Query's internal modelContext ?
1
0
92
Apr ’25
Should you access @State properties from an NSViewController (AppKit / SwiftUI Integration)?
I'm currently working on a project to integrate some SwiftUI components into an existing AppKit application. The application makes extensive use of NSViewControllers. I can easily bridge between AppKit and SwiftUI using a view model that conforms to ObservableObject and is shared between the NSViewController and the SwiftUI View. But it's kind of tedious creating a view model for every view. Is it "safe" and "acceptable" for the NSViewController to "hold on" to the SwiftUI View that it creates and then access its @State or @StateObject properties? The lifecycle of DetailsView, a SwiftUI View, isn't clear to me when viewed through the lens of an NSViewController. Consider the following: import AppKit import SwiftUI struct DetailsView: View { @State var details: String = "" var body: some View { Text(details) } } final class ViewController: NSViewController { private let detailsView: DetailsView init() { self.detailsView = DetailsView() super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { view.addSubview(NSHostingView(rootView: detailsView)) } func updateDetails(_ details: String) { // Is this 'safe' and 'acceptable'? self.detailsView.details = details } } Is the view controller guaranteed to always be updating the correct @State property or is there a chance that the view controller's reference to it somehow becomes stale because of a SwiftUI update?
2
0
68
Apr ’25