Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

PHAssetCreationRequest merges new Burst Photos into "Recently Deleted" instead of Library
Description I am observing a critical issue when saving burst photos using the Photos Framework. If a burst photo with the same burstIdentifier already exists in the "Recently Deleted" album, any new assets saved via PHAssetCreationRequest are automatically merged into that deleted entry instead of appearing in the main Library or "All Photos." Environment Framework: Photos Framework (iOS) API: [[PHPhotoLibrary sharedPhotoLibrary] performChanges:...] Code Snippet The following logic is used to save the burst assets: [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ // 'paths' is a custom object providing the creation request PHAssetCreationRequest *assetCreationRqst = [paths assetCreationRqst]; assetCreationRqst.favorite = [FavorManager.shared isSetDownloadedAssetFavorite:self.curItem]; PHObjectPlaceholder *placeHolder = assetCreationRqst.placeholderForCreatedAsset; localIdentifier = placeHolder.localIdentifier; } completionHandler:^(BOOL success, NSError * _Nullable error) { if (success) { // The handler returns success, but the asset is invisible to the user [weakSelf handleDownloadSuccess:localIdentifier]; } // ... cleanup and completion ... }]; Steps to Reproduce Save a burst photo to the iPhone's built-in Photos app. Manually delete that burst photo so it moves to the "Recently Deleted" album. Execute the code above to save the same burst photo (or a new set containing the same burstIdentifier in its metadata). Check the main Photo Library / "All Photos" view. Observed Result The completionHandler returns success = YES, and a localIdentifier is generated. The photo does not appear in the main Library or "All Photos." The newly saved photo is silently merged into the existing burst set located inside the "Recently Deleted" folder. The user cannot see the new photo unless they manually "Restore" the deleted items from the album. Expected Behavior PHAssetCreationRequest should always result in a visible asset in the user's Library. Even if a matching burstIdentifier exists in "Recently Deleted," the system should treat the new request as a new independent asset or provide an error, rather than hiding it within a deleted collection.
5
0
373
3w
SwipeActions-triggered reorder animation briefly removes row and re-inserts it
I’m seeing a visual glitch in SwiftUI List on iOS 26 when row order changes after a swipeActions action. Setup: List + ForEach of items Items are sorted dynamically by isSelected (unselected first, selected last) Swipe action toggles isSelected Row should animate to new position Problem: On swipe select/unselect, the row sometimes appears to disappear briefly, then reappear in the new position Most visible when unselecting an item from the bottom selected group (it should move to top) Sometimes there is a temporary “empty gap” near the top during the move In some row styling setups, row corner masking also looks wrong during animation What I tried: Different animations (default, easeInOut, spring) Adding/removing small dispatch delay before state change Moving section header content outside List Using custom row backgrounds/corners vs system row styling Keeping stable IDs in ForEach Behavior still appears with native List + swipeActions on iOS 26. So my question is: Is this a known issue/regression with List row move animations on iOS 26? Recommended pattern to keep native swipe actions but avoid this visual artifact? This worked smoothly on iOS 18 with the same approach, and the visual glitch appears only after moving to iOS 26.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
102
3w
Not precise scroll in XCTest
I'm working on UI automation tests using XCUITest for an iOS application (iPhone). My goal is to programmatically scroll a view by a very precise number of pixels (e.g., exactly 500 points down). I understand the scroll(byDeltaX:deltaY:) method is not supported on iPhone, so I'm using the coordinate-based drag method as an alternative. Specifically, I am using XCUICoordinate.press(forDuration:thenDragTo:withVelocity:thenHoldForDuration:) to simulate a drag gesture. I calculate a start and end coordinate with a specific vertical offset in points, expecting the view to scroll by that exact amount. However, I'm observing that the resulting scroll offset is not perfectly accurate. There's a consistent error of several pixels, making the scroll amount unpredictable for precise test assertions. Is there a known limitation to the accuracy of coordinate-based dragging for simulating programmatic scrolling? Are there any alternative methods or best practices within XCUITest to achieve a more reliable and pixel-accurate scroll on iPhone, or is this level of precision simply not achievable with the current framework?
1
0
126
3w
NSTableViewRowAction do not draw the buttons background in macOS Tahoe
Hello, I developed an Open Source Apple Virtualization + QEMU VM manager for macOS, called MacMulator (GitHub repo here). In my app I have a UITableView containing a list of VMs, and I let the user delete or configure a VM through a 2 finger swipe on the corresponding table row. To do this, I added 2 NSTableViewRowActions to my NSTableView, through this code: func tableView(_: NSTableView, rowActionsForRow _: Int, edge _: NSTableView.RowActionEdge) -> [NSTableViewRowAction] { [ NSTableViewRowAction(style: NSTableViewRowAction.Style.destructive, title: NSLocalizedString("VirtualMachineListViewController.delete", comment: ""), handler: { _, index in self.deleteVirtualMachine(index) }), NSTableViewRowAction(style: NSTableViewRowAction.Style.regular, title: NSLocalizedString("VirtualMachineListViewController.edit", comment: ""), handler: { _, index in self.editVirtualMachine(index) }), ] } This actions work fine, but on macOS Tahoe the UI does not draw the background of the 2 buttons, despite the style. The same build in macOS Sequoia work fine (See pictures below). Am I missing something? I did not find and change related to this feature in Tahoe documentation. My UI is not built with SwiftUI, but with storyboards. I don't know if this is relevant. Thanks to whoever will help.
Topic: UI Frameworks SubTopic: General
1
2
113
4w
How to Reload Collection View (DiffableDataSource) after API Finishes Calling
Hello, I have a collection view that uses a diffable data source, and I am initiating an API call while configuring a cell RuntimeCell in the cell registration block inside setupDataSource(). The cell has a runtimeLabel property whose text I am setting inside a configureLabel(movieId:) function. I noticed that the collection view does not automatically refresh the text label once this API call finishes and after setting the text property on a UILabel in the collection view cell to a value retrieved during the API call. I presume this is because I need to call dataSource.apply(snapshot) myself to reload the changes in the collection view after the API call finishes retrieving the runtime data. However, since the API call happens via the configuration of the cell in the cell registration closure, this API call ends up being called infinitely if I call dataSource.apply(snapshot) every time the API call finishes (i.e. calling dataSource.applySnapshot() calls the closure for the cell registration handler which re-triggers the API call). What is the correct architecture to apply to accomplish reloading the collection view so that the text label appears once the API finishes calling? Thank you class MovieDetailViewController: UIViewController { func setupDataSource() { // ... let runTimeCellRegistration = UICollectionView.CellRegistration<RuntimeCell, Item> { cell, indexPath, item in cell.runtimeLabelDelegate = self cell.configureLabel(movieId: self.selectedMovie.id) } dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView, cellProvider: { collectionView, indexPath, itemIdentifier in let section = Section(rawValue: indexPath.section) switch section { //... case .runtime: return collectionView.dequeueConfiguredReusableCell(using: runTimeCellRegistration, for: indexPath, item: itemIdentifier) //... } return nil }) } } protocol RuntimeLabelCellDelegate: AnyObject { func didUpdateRuntime() } class RuntimeCell: UICollectionViewCell { var runtimeLabel: UILabel! //... UI Setup func configureLabel(movieId: Int) { Task { do { let details = try await movieSearchService.fetchMovieDetails(movieId: movieId) await MainActor.run { let minutes = details.runTime let durationText = "\(minutes)m" var emojiText = "" if minutes < 90 { emojiText = "Short & Sweet ⚡️" } else if minutes > 150 { emojiText = "Get the snacks ready 🍿" } runtimeLabel.text = emojiText.isEmpty ? durationText : "\(durationText) • \(emojiText)" runtimeLabelDelegate?.didUpdateRuntime() } } catch { print("Failed to load details: \(error)") } } } } extension MovieDetailViewController: RuntimeLabelCellDelegate { func didUpdateRuntime() { var snapshot = dataSource.snapshot() snapshot.appendItems([.runtime], toSection: .runtime) dataSource.apply(snapshot, animatingDifferences: true) } }
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
88
4w
controller.textDocumentProxy.documentContext not detecting pasted text in Gmail or Email apps
I found an issue related to Gmail and Email apps. When I try to fetch text using controller.textDocumentProxy.documentContext, it works fine every time in my original app and in the Messages app. However, in Gmail or Email apps, after pasting text, controller.textDocumentProxy.documentContext returns nil until the pasted text is edited. The same scenario works correctly in Messages and my original app. i'm trying it from my keyboard extension and my keyboard builded bases on KeyboardKit SDK when i jump to text Document Proxy it's referring me to UITextDocumentProxy
Topic: UI Frameworks SubTopic: UIKit
1
0
304
4w
Data Persistence not functioning upon refresh
Hello, I am attempting to implement a simple button that loads persistent data from a class (see below). Button("Reload Data") { while tableData2.isEmpty == false{ tableData2.remove(at: 0) } while tableView.isEmpty == false{ tableView.remove(at: 0) } //update if csvData.isEmpty == false{ for superRow in csvData[0].tableData2{ tableData2.append(superRow) } for supperRow in csvData[0].tableView{ tableView.append(supperRow) } print("Item at 0: \(csvData[0].tableData2[[0][0]])") print("\(tableData2[0][0])") } else { print("csvData is empty") } } This button DOES work to appropriately print the data stored at the printed location once loaded in initially. The problem is that it doesn’t work across app restarts, which is the whole point of the button. Below I will include the rest of the relevant code with notes: In contentView declaring the persistant variables: Query private var csvData: [csvDataPersist] Environment(\.modelContext) private var modelContext The simple class of data I’m storing/pulling to/from: @Model class csvDataPersist{ var tableView: [[String]] = [] var tableData2: [[String]] = [] init(tableView: [[String]], tableData2: [[String]]) { self.tableView = tableView self.tableData2 = tableData2 } } In (appname)App: I tried both locations of the model container but it didn’t seem to matter var body: some Scene { WindowGroup { ContentView() .modelContainer(for: csvDataPersist.self) } //.modelContainer(for: csvDataPersist.self) .modelContainer(sharedModelContainer) } How I’m attempting to save the data: let newCSVDataPersist = csvDataPersist(tableView: tableView, tableData2: tableData2) //modelContext.rollback() //for superrow in csvData.count{ // csvData[superrow].tableData2.removeAll() //} //modelContext.rollback() //csvData[0].tableData2.removeAll() //csvData[0].tableView.removeAll() if csvData.isEmpty == false { print("not empty, deleting prev data") modelContext.delete(csvData[0]) } else { print("it empty, load data.") } modelContext.insert(newCSVDataPersist) //try modelContext.save() Note that I’ve tried just about every combination of enabling and disabling the commented out lines. This is the part of the code I am the least confident in, but after trying for hours to troubleshoot on my own I would appreciate any input from the community. Something else that may be of note, in a previous attempt, upon a second startup, the terminal would print: "coredata: error: error: persistent history (random number) has to be truncated due to the following entities being removed: ( csvdatapersist )" Why is csvDataPersist getting removed? What is it getting removed by? Looking up this error was fruitless. Most sites instructed me to basically hard reset my simulators, clean the build, restart my computer, and try again. I've done all of these things about a hundred times at this point, with no results. Any help would be much appreciated!
3
0
103
4w
Access Relationship value from deleted model tombstone in SwiftData.
I’m developing an app using SwiftData. In my app, I have two models: User and Address. A user can have multiple addresses. I’m trying to use SwiftData History tracking to implement some logic when addresses are deleted. Specifically, I need to determine which user the address belonged to. From the documentation, I understand that you can preserve attributes from deleted models in a tombstone object using @Attribute(.preserveValueOnDeletion). However, this isn’t working when I try to apply this to a relationship value. Below is a simplified example of my attempts so far. I suspect that simply adding @Attribute(.preserveValueOnDeletion) to a relationship isn’t feasible. If that’s indeed the case, what would be the recommended approach to identify the user associated with an address after it has been deleted? Thank you. @Model class User { var name: String @Relationship(deleteRule: .cascade, inverse: \Address.user) var addresses: [Address] = [] init(name: String) { self.name = name } } @Model class Address { var adress1: String var address2: String var city: String var zip: String @Attribute(.preserveValueOnDeletion) var user: User? init(adress1: String, address2: String, city: String, zip: String) { self.adress1 = adress1 self.address2 = address2 self.city = city self.zip = zip self.user = user } } for transaction in transactions { for change in transaction.changes { switch change { case .delete(let deleted): if let deleted = deleted as? any HistoryDelete<Address> { if let user = deleted.tombstone[\.user] { //this is never executed } } default: break } } }
1
0
90
4w
What is the lifecycle of onReceive subscriptions in SwiftUI views?
I'm trying to better understand how the onReceive modifier behaves in SwiftUI, specifically how its subscription lifecycle relates to view updates. Consider this example: TextField("Name", text: $name) .onReceive(Just(name)) { value in print(value) } This closure runs every time name changes. A common explanation is that SwiftUI recomputes body, which creates a new Just(name) publisher each time. However, this raises some questions for me about how onReceive actually works internally: When SwiftUI recomputes body, is the onReceive modifier recreated and resubscribed? Does SwiftUI automatically cancel the previous subscription when the view updates?
0
0
55
4w
Internal inconsistency in menus - menu warnings...
I get warnings like this on each project I build while debugging.. Internal inconsistency in menus - menu <NSMenu: 0x8b4b49ec0> Title: Help Supermenu: 0x8b4b49f80 (Main Menu), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( "<NSMenuItem: 0x8b5771720 Metal4C Help, ke='Command-?'>" ) believes it has <NSMenu: 0x8b4b49f80> Title: Main Menu Supermenu: 0x0 (None), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( ) as a supermenu, but the supermenu does not seem to have any item with that submenu What am I doing wrong? I get these errors even if I create a default app with no code?
Topic: UI Frameworks SubTopic: AppKit
5
1
219
4w
Credit Card Autofill Not Working in React Native TextInput
Hello, I'm currently investigating an issue related to iOS credit card autofill (Payments & Card Details) in our mobile application. Our app is built using React Native, and we are implementing card input fields using TextInput with the required autofill configuration: autoComplete="cc-number" textContentType="creditCardNumber" Despite correctly configuring these properties, credit card autofill is not being triggered on iOS devices. I would appreciate clarification on: Is credit card autofill officially supported for React Native TextInput fields using autoComplete="cc-number" and textContentType="creditCardNumber"? Are there any additional requirements (entitlements, associated domains, specific configurations, etc.) needed for payment autofill to work? Is autofill expected to work inside WKWebView contexts? Are there any known limitations or restrictions for third-party frameworks such as React Native? I would appreciate any guidance or documentation you can share regarding the expected behavior and official support for this scenario
0
0
64
4w
UIScreen.isCaptured and sceneCaptureState report inactive while system screen recording continues when Live Activity is expanded
Hi, I’m trying to reliably detect when system screen recording finishes, and I’m observing behavior that I don’t fully understand when a Live Activity is expanded via Dynamic Island. Environment Devices: iPhone 16 Pro iOS: 26.2 Xcode: 26.2 Using UIScreen.isCaptured and UIWindowScene.sceneCaptureState Implementation: I observe capture state like this: private var observation: NSKeyValueObservation? func startObserving() { observation = UIScreen.main.observe(\.isCaptured, options: [.new]) { _, change in print("isCaptured:", change.newValue ?? false) } } I also check: window.traitCollection.sceneCaptureState Steps to Reproduce Start system screen recording from Control Center. Confirm UIScreen.main.isCaptured == true. Expand a Live Activity via the Dynamic Island (e.g. timer or call). Observe capture state values while the Live Activity UI is expanded. Observed Behavior While screen recording is still active: UIScreen.main.isCaptured becomes false sceneCaptureState becomes .inactive This state persists while the recording Live Activity is expanded The system recording indicator remains visible The device continues recording Expected Behavior (or Clarification Needed) My understanding was that UIScreen.isCaptured indicates whether the device screen is currently being captured (e.g. screen recording or mirroring). However, this behavior suggests that both isCaptured and sceneCaptureState reflect whether the current scene is part of the capture surface, rather than whether device-level recording is active. Is this the intended behavior when system-owned surfaces (such as expanded Live Activities) are promoted above the app’s scene? If so: Is there any supported way to reliably detect device-level screen recording state (as opposed to scene-level capture participation), in order to trigger logic when recording finishes? Thank you for any clarification.
Topic: UI Frameworks SubTopic: UIKit
0
0
68
Mar ’26
Obscure assertion crash in com.apple.NSScrollingConcurrentVBLMonitor thread
I have received a few crash reports for my app "Find Any File" with an assertion failure as follows: assertion failure: "displayTiming != ((void *)0)" -&gt; %lld Googling this turns up nothing, though. I wonder if someone has some insight into why this might happen, and how to prevent it. One reporting user suggests that it happens when my app shows a very long list of items in an NSTableView (&gt;10000 elements). I have 4 reports from 3 users, and the main thread is doing something related to the table view each time, though not the same (the few other threads are all idle): Crash 1, in macOS 14.0 (23A344: Thread 0:: Dispatch queue: com.apple.main-thread 0 libobjc.A.dylib 0x182c69400 objc_msgSend + 0 1 AppKit 0x186f15400 -[CALayer(NSViewVisibleRect) NS_viewVisibleRectDidChange] + 40 2 AppKit 0x186900e10 NSViewHierarchyInvalidateVisibleRect + 276 3 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 4 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 5 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 6 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 7 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 8 AppKit 0x1869990e0 -[NSView translateOriginToPoint:] + 164 9 AppKit 0x186984108 -[NSClipView _immediateScrollToPoint:] + 420 10 AppKit 0x186983eb8 -[NSClipView scrollToPoint:] + 184 11 AppKit 0x186998d80 -[NSScrollView scrollClipView:toPoint:] + 84 12 AppKit 0x1869448dc -[NSClipView _scrollTo:animateScroll:flashScrollerKnobs:] + 480 13 AppKit 0x186b65b24 __62-[NSScrollingBehaviorConcurrentVBL _stopGestureScrollTracking]_block_invoke + 192 14 AppKit 0x186e6a6e8 ___NSMainRunLoopPerformBlockInModes_block_invoke + 44 15 CoreFoundation 0x18310b8c0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28 Crash 2, in macOS 14.1.1 (23B81): Thread 0:: Dispatch queue: com.apple.main-thread 0 CoreFoundation 0x18ba401f4 DYLD-STUB$$_Block_object_assign + 0 1 libsystem_blocks.dylib 0x18b506118 _call_copy_helpers_excp + 80 2 libsystem_blocks.dylib 0x18b505c68 _Block_copy + 376 3 libdispatch.dylib 0x18b641c7c _dispatch_Block_copy + 32 4 libdispatch.dylib 0x18b658df0 _dispatch_source_set_handler + 92 5 CoreFoundation 0x18b99e1e4 __CFRunLoopCopyMode + 540 6 CoreFoundation 0x18b8b7458 CFRunLoopAddObserver + 220 7 AppKit 0x18f0a687c _PerfAddRunLoopObserver + 192 8 AppKit 0x18f87cd60 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 368 9 AppKit 0x18f323318 -[_NSScrollingConcurrentEventMonitor startMonitoring] + 380 10 AppKit 0x18f321df8 -[NSScrollingBehaviorConcurrentVBL _scrollView:trackGestureScrollWithEvent:] + 884 11 AppKit 0x18f2e67f8 -[NSScrollingBehaviorConcurrentVBL scrollView:scrollWheelWithEvent:] + 512 12 AppKit 0x18f241770 forwardMethod + 252 13 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 14 AppKit 0x18f241770 forwardMethod + 252 15 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 16 AppKit 0x18f241770 forwardMethod + 252 17 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 18 AppKit 0x18f241770 forwardMethod + 252 19 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 20 AppKit 0x18fc45880 -[NSCollectionView scrollWheel:] + 180 21 AppKit 0x18f241770 forwardMethod + 252 22 AppKit 0x18f241770 forwardMethod + 252 23 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 24 AppKit 0x18f241770 forwardMethod + 252 25 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 26 AppKit 0x18f241770 forwardMethod + 252 27 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 28 AppKit 0x18f1d27b0 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 652 As you can see, there's no code of mine involved at the time of crash. The other (and older) reports are similar, in macOS 13.6.1 and macOS 13.1. All four happened on ARM architecture (which may not be significant due to small number of samples). Memory use of app was not critical (in one case it was about 9 GB total, in others below 4 GB). The "Binary Images" section only lists Apple libs, apart from my app's. So, there seems to be no 3rd party ext involved. I've attached a full report as well. Full report of Crash 1
2
0
1.3k
Mar ’26
How do you make a resizable segmented control in SwiftUI for macOS?
In SwiftUI for macOS, how do I configure a Picker as a segmented control to have a flexible width? This design pattern is present in Xcode 26 at the top of the sidebar and inspector panel. I can't figure out the combination of view modifiers to achieve a similar look. import SwiftUI struct ContentView: View { @State private var selection = 0 var body: some View { VStack { Picker("", selection: $selection) { Image(systemName: "doc") Image(systemName: "folder") Image(systemName: "gear") Image(systemName: "globe") .frame(maxWidth: .infinity) // Doesn't do anything. } .labelsHidden() .pickerStyle(.segmented) .frame(maxWidth: .infinity) // Doesn't affect segment sizes. Spacer() } } } I want the entire Picker to fill the width and for each segment to be of equal widths. How? In AppKit I would use AutoLayout for the flexible width and NSSegmentedControl.segmentDistribution for the segment widths. Is there a SwiftUI equivalent? macOS 26 / Xcode 26.3
Topic: UI Frameworks SubTopic: SwiftUI Tags:
0
0
97
Mar ’26
SwiftData with shared and private containers
I was hoping for an update of SwiftData which adopted the use of shared and public CloudKit containers, in the same way it does for the private CloudKit container. So firstly, a big request to any Apple devs reading, for this to be a thing! Secondly, what would be a sensible way of adding a shared container in CloudKit to an existing app that is already using SwiftData? Would it be possible to use the new DataStore method to manage CloudKit syncing with a public or shared container?
12
18
4.0k
Mar ’26
Active Quicklook extension is ignored
When you have multiple Apps on the Mac which all provide Quicklook extensions for the same file type, then I would assume that if I activate one of these Quicklook extensions in the system settings, this one would be used. But this doesn't seem to be the case. It looks like the macOS just looks the very first extension it can find for a certain file type, and if this Quicklook extension is switched off, the file can not be previewed anymore. The macOS just doesn't bother to look for the other existing quicklook extension for this file, even if this other is enabled. The only option right now to get this other extension to be used by the system would be to completely delete the first App, so its extension is deleted as well. Is this really the way how it is supposed to work? How can this be fixed? Can I tell my users something else than "just delete the other App"?
0
0
137
Mar ’26
Detect closing of tab (NSWindowTab) in WindowGroup
I have a SwiftUI app displaying tabbed windows (as NSWindowTab) in a WindowGroup: import SwiftUI @main struct TabTestApp: App { var body: some Scene { WindowGroup{ ContentView() // Hasn't any content of relevance to this question. }.commands{ CommandGroup(after: .newItem) { Button("New Tab") { guard let currentWindow = NSApp.keyWindow, let windowController = currentWindow.windowController else { return } windowController.newWindowForTab(nil) guard let newWindow = NSApp.keyWindow else { return } if currentWindow != newWindow { currentWindow.addTabbedWindow(newWindow, ordered: .above) } }.keyboardShortcut(.init("t", modifiers: [.command])) } } } } Is there a way to detect the closing of one or multiple tabs, e.g. when the user clicks on the tab bar's "Close Other Tabs" option or pushes CMD + W in order to ask the user whether he or she wants to save changes? What I've tried to no avail: Intercept windowWillClose👉Won't be called if a single tab within a window is closed (but only once the last tab of a window is closed). Handling onDissapear()👉Doesn't work since the closing cannot be cancelled. Using DocumentGroup 👉Doesn't work since the app in question isn't about documents (i.e., files which are stored externally), but about data that's stored in a database. Many thanks! Related threads: Preserve all tabs of last window on close. (Like Finder) Detect Close Window vs Close Tab
0
0
75
Mar ’26
UIScrollView Layout issue
I run into a layout problem where I cannot center an image inside ScrollView which is also inside Navigation Controller. The problem is surely the fact that there is a navigation bar because using this view without NavigationContoller works fine and the image is centered but I don’t know how to account for the space that navigation bar takes up. Here is the code: import UIKit class PhotoViewController: UIViewController { var photoName: String private lazy var photoView = { let image = UIImageView() image.translatesAutoresizingMaskIntoConstraints = false image.contentMode = .scaleAspectFit image.clipsToBounds = true return image }() var photoViewBottomConstraint: NSLayoutConstraint? var photoViewLeadingConstraint: NSLayoutConstraint? var photoViewTopConstraint: NSLayoutConstraint? var photoViewTrailingConstraint: NSLayoutConstraint? private lazy var scrollView = { let sv = UIScrollView() sv.translatesAutoresizingMaskIntoConstraints = false return sv }() override func viewDidLoad() { super.viewDidLoad() setupUI() } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() updateMinZoomScaleForSize(view.bounds.size) } func updateMinZoomScaleForSize(_ size: CGSize) { let widthScale = size.width / photoView.bounds.width let heightScale = size.height / photoView.bounds.height let minScale = min(widthScale, heightScale) scrollView.minimumZoomScale = minScale scrollView.zoomScale = minScale } func setupUI() { photoView.image = UIImage(named: photoName) scrollView.delegate = self view.addSubview(scrollView) scrollView.addSubview(photoView) setupConstraints() } func setupConstraints() { NSLayoutConstraint.activate([ scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) photoViewLeadingConstraint = NSLayoutConstraint( item: photoView, attribute: .leading, relatedBy: .equal, toItem: scrollView, attribute: .leading, multiplier: 1, constant: 0 ) photoViewTopConstraint = NSLayoutConstraint( item: photoView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1, constant: 0 ) photoViewTrailingConstraint = NSLayoutConstraint( item: photoView, attribute: .trailing, relatedBy: .equal, toItem: scrollView, attribute: .trailing, multiplier: 1, constant: 0 ) photoViewBottomConstraint = NSLayoutConstraint( item: photoView, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1, constant: 0 ) photoViewLeadingConstraint?.isActive = true photoViewTopConstraint?.isActive = true photoViewTrailingConstraint?.isActive = true photoViewBottomConstraint?.isActive = true } init(photoName: String) { self.photoName = photoName super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } extension PhotoViewController: UIScrollViewDelegate { func viewForZooming(in scrollView: UIScrollView) -> UIView? { photoView } func scrollViewDidZoom(_ scrollView: UIScrollView) { updateConstraintsForSize(view.bounds.size) } func updateConstraintsForSize(_ size: CGSize) { let yOffset = max(0, (size.height - photoView.frame.height) / 2) photoViewTopConstraint?.constant = yOffset photoViewBottomConstraint?.constant = yOffset let xOffset = max(0, (size.width - photoView.frame.width) / 2) photoViewLeadingConstraint?.constant = xOffset photoViewTrailingConstraint?.constant = xOffset view.layoutIfNeeded() } }
3
0
181
Feb ’26
UIActivityViewController not vertically scrollable when sharing CSV on specific device (Save option unreachable)
Platform UIKit iOS UIActivityViewController Environment Device (issue reported): iPhone 16 iOS Version: 26.2 App Type: UIKit / Swift (standard modal presentation of UIActivityViewController) Summary When presenting UIActivityViewController to share a CSV file, the share sheet does not allow vertical scrolling, making lower actions (including Save to Files) unreachable. The same flow works correctly when sharing a PDF, and the issue cannot be reproduced on other test devices. Steps to Reproduce Launch the app and log in Navigate to More → Reports Tap Export Report Choose Export Report (CSV) Observe the share sheet Expected Result The user should be able to vertically scroll the share sheet All share actions (including Save to Files) should be reachable Actual Result Share sheet opens but vertical scrolling is disabled Lower options (including Save to Files) are not reachable No crash or console errors
3
0
409
Feb ’26
PHAssetCreationRequest merges new Burst Photos into "Recently Deleted" instead of Library
Description I am observing a critical issue when saving burst photos using the Photos Framework. If a burst photo with the same burstIdentifier already exists in the "Recently Deleted" album, any new assets saved via PHAssetCreationRequest are automatically merged into that deleted entry instead of appearing in the main Library or "All Photos." Environment Framework: Photos Framework (iOS) API: [[PHPhotoLibrary sharedPhotoLibrary] performChanges:...] Code Snippet The following logic is used to save the burst assets: [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ // 'paths' is a custom object providing the creation request PHAssetCreationRequest *assetCreationRqst = [paths assetCreationRqst]; assetCreationRqst.favorite = [FavorManager.shared isSetDownloadedAssetFavorite:self.curItem]; PHObjectPlaceholder *placeHolder = assetCreationRqst.placeholderForCreatedAsset; localIdentifier = placeHolder.localIdentifier; } completionHandler:^(BOOL success, NSError * _Nullable error) { if (success) { // The handler returns success, but the asset is invisible to the user [weakSelf handleDownloadSuccess:localIdentifier]; } // ... cleanup and completion ... }]; Steps to Reproduce Save a burst photo to the iPhone's built-in Photos app. Manually delete that burst photo so it moves to the "Recently Deleted" album. Execute the code above to save the same burst photo (or a new set containing the same burstIdentifier in its metadata). Check the main Photo Library / "All Photos" view. Observed Result The completionHandler returns success = YES, and a localIdentifier is generated. The photo does not appear in the main Library or "All Photos." The newly saved photo is silently merged into the existing burst set located inside the "Recently Deleted" folder. The user cannot see the new photo unless they manually "Restore" the deleted items from the album. Expected Behavior PHAssetCreationRequest should always result in a visible asset in the user's Library. Even if a matching burstIdentifier exists in "Recently Deleted," the system should treat the new request as a new independent asset or provide an error, rather than hiding it within a deleted collection.
Replies
5
Boosts
0
Views
373
Activity
3w
SwipeActions-triggered reorder animation briefly removes row and re-inserts it
I’m seeing a visual glitch in SwiftUI List on iOS 26 when row order changes after a swipeActions action. Setup: List + ForEach of items Items are sorted dynamically by isSelected (unselected first, selected last) Swipe action toggles isSelected Row should animate to new position Problem: On swipe select/unselect, the row sometimes appears to disappear briefly, then reappear in the new position Most visible when unselecting an item from the bottom selected group (it should move to top) Sometimes there is a temporary “empty gap” near the top during the move In some row styling setups, row corner masking also looks wrong during animation What I tried: Different animations (default, easeInOut, spring) Adding/removing small dispatch delay before state change Moving section header content outside List Using custom row backgrounds/corners vs system row styling Keeping stable IDs in ForEach Behavior still appears with native List + swipeActions on iOS 26. So my question is: Is this a known issue/regression with List row move animations on iOS 26? Recommended pattern to keep native swipe actions but avoid this visual artifact? This worked smoothly on iOS 18 with the same approach, and the visual glitch appears only after moving to iOS 26.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
102
Activity
3w
Not precise scroll in XCTest
I'm working on UI automation tests using XCUITest for an iOS application (iPhone). My goal is to programmatically scroll a view by a very precise number of pixels (e.g., exactly 500 points down). I understand the scroll(byDeltaX:deltaY:) method is not supported on iPhone, so I'm using the coordinate-based drag method as an alternative. Specifically, I am using XCUICoordinate.press(forDuration:thenDragTo:withVelocity:thenHoldForDuration:) to simulate a drag gesture. I calculate a start and end coordinate with a specific vertical offset in points, expecting the view to scroll by that exact amount. However, I'm observing that the resulting scroll offset is not perfectly accurate. There's a consistent error of several pixels, making the scroll amount unpredictable for precise test assertions. Is there a known limitation to the accuracy of coordinate-based dragging for simulating programmatic scrolling? Are there any alternative methods or best practices within XCUITest to achieve a more reliable and pixel-accurate scroll on iPhone, or is this level of precision simply not achievable with the current framework?
Replies
1
Boosts
0
Views
126
Activity
3w
NSTableViewRowAction do not draw the buttons background in macOS Tahoe
Hello, I developed an Open Source Apple Virtualization + QEMU VM manager for macOS, called MacMulator (GitHub repo here). In my app I have a UITableView containing a list of VMs, and I let the user delete or configure a VM through a 2 finger swipe on the corresponding table row. To do this, I added 2 NSTableViewRowActions to my NSTableView, through this code: func tableView(_: NSTableView, rowActionsForRow _: Int, edge _: NSTableView.RowActionEdge) -> [NSTableViewRowAction] { [ NSTableViewRowAction(style: NSTableViewRowAction.Style.destructive, title: NSLocalizedString("VirtualMachineListViewController.delete", comment: ""), handler: { _, index in self.deleteVirtualMachine(index) }), NSTableViewRowAction(style: NSTableViewRowAction.Style.regular, title: NSLocalizedString("VirtualMachineListViewController.edit", comment: ""), handler: { _, index in self.editVirtualMachine(index) }), ] } This actions work fine, but on macOS Tahoe the UI does not draw the background of the 2 buttons, despite the style. The same build in macOS Sequoia work fine (See pictures below). Am I missing something? I did not find and change related to this feature in Tahoe documentation. My UI is not built with SwiftUI, but with storyboards. I don't know if this is relevant. Thanks to whoever will help.
Topic: UI Frameworks SubTopic: General
Replies
1
Boosts
2
Views
113
Activity
4w
How to Reload Collection View (DiffableDataSource) after API Finishes Calling
Hello, I have a collection view that uses a diffable data source, and I am initiating an API call while configuring a cell RuntimeCell in the cell registration block inside setupDataSource(). The cell has a runtimeLabel property whose text I am setting inside a configureLabel(movieId:) function. I noticed that the collection view does not automatically refresh the text label once this API call finishes and after setting the text property on a UILabel in the collection view cell to a value retrieved during the API call. I presume this is because I need to call dataSource.apply(snapshot) myself to reload the changes in the collection view after the API call finishes retrieving the runtime data. However, since the API call happens via the configuration of the cell in the cell registration closure, this API call ends up being called infinitely if I call dataSource.apply(snapshot) every time the API call finishes (i.e. calling dataSource.applySnapshot() calls the closure for the cell registration handler which re-triggers the API call). What is the correct architecture to apply to accomplish reloading the collection view so that the text label appears once the API finishes calling? Thank you class MovieDetailViewController: UIViewController { func setupDataSource() { // ... let runTimeCellRegistration = UICollectionView.CellRegistration<RuntimeCell, Item> { cell, indexPath, item in cell.runtimeLabelDelegate = self cell.configureLabel(movieId: self.selectedMovie.id) } dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView, cellProvider: { collectionView, indexPath, itemIdentifier in let section = Section(rawValue: indexPath.section) switch section { //... case .runtime: return collectionView.dequeueConfiguredReusableCell(using: runTimeCellRegistration, for: indexPath, item: itemIdentifier) //... } return nil }) } } protocol RuntimeLabelCellDelegate: AnyObject { func didUpdateRuntime() } class RuntimeCell: UICollectionViewCell { var runtimeLabel: UILabel! //... UI Setup func configureLabel(movieId: Int) { Task { do { let details = try await movieSearchService.fetchMovieDetails(movieId: movieId) await MainActor.run { let minutes = details.runTime let durationText = "\(minutes)m" var emojiText = "" if minutes < 90 { emojiText = "Short & Sweet ⚡️" } else if minutes > 150 { emojiText = "Get the snacks ready 🍿" } runtimeLabel.text = emojiText.isEmpty ? durationText : "\(durationText) • \(emojiText)" runtimeLabelDelegate?.didUpdateRuntime() } } catch { print("Failed to load details: \(error)") } } } } extension MovieDetailViewController: RuntimeLabelCellDelegate { func didUpdateRuntime() { var snapshot = dataSource.snapshot() snapshot.appendItems([.runtime], toSection: .runtime) dataSource.apply(snapshot, animatingDifferences: true) } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
0
Boosts
0
Views
88
Activity
4w
controller.textDocumentProxy.documentContext not detecting pasted text in Gmail or Email apps
I found an issue related to Gmail and Email apps. When I try to fetch text using controller.textDocumentProxy.documentContext, it works fine every time in my original app and in the Messages app. However, in Gmail or Email apps, after pasting text, controller.textDocumentProxy.documentContext returns nil until the pasted text is edited. The same scenario works correctly in Messages and my original app. i'm trying it from my keyboard extension and my keyboard builded bases on KeyboardKit SDK when i jump to text Document Proxy it's referring me to UITextDocumentProxy
Topic: UI Frameworks SubTopic: UIKit
Replies
1
Boosts
0
Views
304
Activity
4w
Data Persistence not functioning upon refresh
Hello, I am attempting to implement a simple button that loads persistent data from a class (see below). Button("Reload Data") { while tableData2.isEmpty == false{ tableData2.remove(at: 0) } while tableView.isEmpty == false{ tableView.remove(at: 0) } //update if csvData.isEmpty == false{ for superRow in csvData[0].tableData2{ tableData2.append(superRow) } for supperRow in csvData[0].tableView{ tableView.append(supperRow) } print("Item at 0: \(csvData[0].tableData2[[0][0]])") print("\(tableData2[0][0])") } else { print("csvData is empty") } } This button DOES work to appropriately print the data stored at the printed location once loaded in initially. The problem is that it doesn’t work across app restarts, which is the whole point of the button. Below I will include the rest of the relevant code with notes: In contentView declaring the persistant variables: Query private var csvData: [csvDataPersist] Environment(\.modelContext) private var modelContext The simple class of data I’m storing/pulling to/from: @Model class csvDataPersist{ var tableView: [[String]] = [] var tableData2: [[String]] = [] init(tableView: [[String]], tableData2: [[String]]) { self.tableView = tableView self.tableData2 = tableData2 } } In (appname)App: I tried both locations of the model container but it didn’t seem to matter var body: some Scene { WindowGroup { ContentView() .modelContainer(for: csvDataPersist.self) } //.modelContainer(for: csvDataPersist.self) .modelContainer(sharedModelContainer) } How I’m attempting to save the data: let newCSVDataPersist = csvDataPersist(tableView: tableView, tableData2: tableData2) //modelContext.rollback() //for superrow in csvData.count{ // csvData[superrow].tableData2.removeAll() //} //modelContext.rollback() //csvData[0].tableData2.removeAll() //csvData[0].tableView.removeAll() if csvData.isEmpty == false { print("not empty, deleting prev data") modelContext.delete(csvData[0]) } else { print("it empty, load data.") } modelContext.insert(newCSVDataPersist) //try modelContext.save() Note that I’ve tried just about every combination of enabling and disabling the commented out lines. This is the part of the code I am the least confident in, but after trying for hours to troubleshoot on my own I would appreciate any input from the community. Something else that may be of note, in a previous attempt, upon a second startup, the terminal would print: "coredata: error: error: persistent history (random number) has to be truncated due to the following entities being removed: ( csvdatapersist )" Why is csvDataPersist getting removed? What is it getting removed by? Looking up this error was fruitless. Most sites instructed me to basically hard reset my simulators, clean the build, restart my computer, and try again. I've done all of these things about a hundred times at this point, with no results. Any help would be much appreciated!
Replies
3
Boosts
0
Views
103
Activity
4w
Access Relationship value from deleted model tombstone in SwiftData.
I’m developing an app using SwiftData. In my app, I have two models: User and Address. A user can have multiple addresses. I’m trying to use SwiftData History tracking to implement some logic when addresses are deleted. Specifically, I need to determine which user the address belonged to. From the documentation, I understand that you can preserve attributes from deleted models in a tombstone object using @Attribute(.preserveValueOnDeletion). However, this isn’t working when I try to apply this to a relationship value. Below is a simplified example of my attempts so far. I suspect that simply adding @Attribute(.preserveValueOnDeletion) to a relationship isn’t feasible. If that’s indeed the case, what would be the recommended approach to identify the user associated with an address after it has been deleted? Thank you. @Model class User { var name: String @Relationship(deleteRule: .cascade, inverse: \Address.user) var addresses: [Address] = [] init(name: String) { self.name = name } } @Model class Address { var adress1: String var address2: String var city: String var zip: String @Attribute(.preserveValueOnDeletion) var user: User? init(adress1: String, address2: String, city: String, zip: String) { self.adress1 = adress1 self.address2 = address2 self.city = city self.zip = zip self.user = user } } for transaction in transactions { for change in transaction.changes { switch change { case .delete(let deleted): if let deleted = deleted as? any HistoryDelete<Address> { if let user = deleted.tombstone[\.user] { //this is never executed } } default: break } } }
Replies
1
Boosts
0
Views
90
Activity
4w
What is the lifecycle of onReceive subscriptions in SwiftUI views?
I'm trying to better understand how the onReceive modifier behaves in SwiftUI, specifically how its subscription lifecycle relates to view updates. Consider this example: TextField("Name", text: $name) .onReceive(Just(name)) { value in print(value) } This closure runs every time name changes. A common explanation is that SwiftUI recomputes body, which creates a new Just(name) publisher each time. However, this raises some questions for me about how onReceive actually works internally: When SwiftUI recomputes body, is the onReceive modifier recreated and resubscribed? Does SwiftUI automatically cancel the previous subscription when the view updates?
Replies
0
Boosts
0
Views
55
Activity
4w
Internal inconsistency in menus - menu warnings...
I get warnings like this on each project I build while debugging.. Internal inconsistency in menus - menu <NSMenu: 0x8b4b49ec0> Title: Help Supermenu: 0x8b4b49f80 (Main Menu), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( "<NSMenuItem: 0x8b5771720 Metal4C Help, ke='Command-?'>" ) believes it has <NSMenu: 0x8b4b49f80> Title: Main Menu Supermenu: 0x0 (None), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( ) as a supermenu, but the supermenu does not seem to have any item with that submenu What am I doing wrong? I get these errors even if I create a default app with no code?
Topic: UI Frameworks SubTopic: AppKit
Replies
5
Boosts
1
Views
219
Activity
4w
Credit Card Autofill Not Working in React Native TextInput
Hello, I'm currently investigating an issue related to iOS credit card autofill (Payments & Card Details) in our mobile application. Our app is built using React Native, and we are implementing card input fields using TextInput with the required autofill configuration: autoComplete="cc-number" textContentType="creditCardNumber" Despite correctly configuring these properties, credit card autofill is not being triggered on iOS devices. I would appreciate clarification on: Is credit card autofill officially supported for React Native TextInput fields using autoComplete="cc-number" and textContentType="creditCardNumber"? Are there any additional requirements (entitlements, associated domains, specific configurations, etc.) needed for payment autofill to work? Is autofill expected to work inside WKWebView contexts? Are there any known limitations or restrictions for third-party frameworks such as React Native? I would appreciate any guidance or documentation you can share regarding the expected behavior and official support for this scenario
Replies
0
Boosts
0
Views
64
Activity
4w
UIScreen.isCaptured and sceneCaptureState report inactive while system screen recording continues when Live Activity is expanded
Hi, I’m trying to reliably detect when system screen recording finishes, and I’m observing behavior that I don’t fully understand when a Live Activity is expanded via Dynamic Island. Environment Devices: iPhone 16 Pro iOS: 26.2 Xcode: 26.2 Using UIScreen.isCaptured and UIWindowScene.sceneCaptureState Implementation: I observe capture state like this: private var observation: NSKeyValueObservation? func startObserving() { observation = UIScreen.main.observe(\.isCaptured, options: [.new]) { _, change in print("isCaptured:", change.newValue ?? false) } } I also check: window.traitCollection.sceneCaptureState Steps to Reproduce Start system screen recording from Control Center. Confirm UIScreen.main.isCaptured == true. Expand a Live Activity via the Dynamic Island (e.g. timer or call). Observe capture state values while the Live Activity UI is expanded. Observed Behavior While screen recording is still active: UIScreen.main.isCaptured becomes false sceneCaptureState becomes .inactive This state persists while the recording Live Activity is expanded The system recording indicator remains visible The device continues recording Expected Behavior (or Clarification Needed) My understanding was that UIScreen.isCaptured indicates whether the device screen is currently being captured (e.g. screen recording or mirroring). However, this behavior suggests that both isCaptured and sceneCaptureState reflect whether the current scene is part of the capture surface, rather than whether device-level recording is active. Is this the intended behavior when system-owned surfaces (such as expanded Live Activities) are promoted above the app’s scene? If so: Is there any supported way to reliably detect device-level screen recording state (as opposed to scene-level capture participation), in order to trigger logic when recording finishes? Thank you for any clarification.
Topic: UI Frameworks SubTopic: UIKit
Replies
0
Boosts
0
Views
68
Activity
Mar ’26
Obscure assertion crash in com.apple.NSScrollingConcurrentVBLMonitor thread
I have received a few crash reports for my app "Find Any File" with an assertion failure as follows: assertion failure: "displayTiming != ((void *)0)" -&gt; %lld Googling this turns up nothing, though. I wonder if someone has some insight into why this might happen, and how to prevent it. One reporting user suggests that it happens when my app shows a very long list of items in an NSTableView (&gt;10000 elements). I have 4 reports from 3 users, and the main thread is doing something related to the table view each time, though not the same (the few other threads are all idle): Crash 1, in macOS 14.0 (23A344: Thread 0:: Dispatch queue: com.apple.main-thread 0 libobjc.A.dylib 0x182c69400 objc_msgSend + 0 1 AppKit 0x186f15400 -[CALayer(NSViewVisibleRect) NS_viewVisibleRectDidChange] + 40 2 AppKit 0x186900e10 NSViewHierarchyInvalidateVisibleRect + 276 3 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 4 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 5 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 6 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 7 AppKit 0x186900db0 NSViewHierarchyInvalidateVisibleRect + 180 8 AppKit 0x1869990e0 -[NSView translateOriginToPoint:] + 164 9 AppKit 0x186984108 -[NSClipView _immediateScrollToPoint:] + 420 10 AppKit 0x186983eb8 -[NSClipView scrollToPoint:] + 184 11 AppKit 0x186998d80 -[NSScrollView scrollClipView:toPoint:] + 84 12 AppKit 0x1869448dc -[NSClipView _scrollTo:animateScroll:flashScrollerKnobs:] + 480 13 AppKit 0x186b65b24 __62-[NSScrollingBehaviorConcurrentVBL _stopGestureScrollTracking]_block_invoke + 192 14 AppKit 0x186e6a6e8 ___NSMainRunLoopPerformBlockInModes_block_invoke + 44 15 CoreFoundation 0x18310b8c0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28 Crash 2, in macOS 14.1.1 (23B81): Thread 0:: Dispatch queue: com.apple.main-thread 0 CoreFoundation 0x18ba401f4 DYLD-STUB$$_Block_object_assign + 0 1 libsystem_blocks.dylib 0x18b506118 _call_copy_helpers_excp + 80 2 libsystem_blocks.dylib 0x18b505c68 _Block_copy + 376 3 libdispatch.dylib 0x18b641c7c _dispatch_Block_copy + 32 4 libdispatch.dylib 0x18b658df0 _dispatch_source_set_handler + 92 5 CoreFoundation 0x18b99e1e4 __CFRunLoopCopyMode + 540 6 CoreFoundation 0x18b8b7458 CFRunLoopAddObserver + 220 7 AppKit 0x18f0a687c _PerfAddRunLoopObserver + 192 8 AppKit 0x18f87cd60 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 368 9 AppKit 0x18f323318 -[_NSScrollingConcurrentEventMonitor startMonitoring] + 380 10 AppKit 0x18f321df8 -[NSScrollingBehaviorConcurrentVBL _scrollView:trackGestureScrollWithEvent:] + 884 11 AppKit 0x18f2e67f8 -[NSScrollingBehaviorConcurrentVBL scrollView:scrollWheelWithEvent:] + 512 12 AppKit 0x18f241770 forwardMethod + 252 13 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 14 AppKit 0x18f241770 forwardMethod + 252 15 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 16 AppKit 0x18f241770 forwardMethod + 252 17 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 18 AppKit 0x18f241770 forwardMethod + 252 19 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 20 AppKit 0x18fc45880 -[NSCollectionView scrollWheel:] + 180 21 AppKit 0x18f241770 forwardMethod + 252 22 AppKit 0x18f241770 forwardMethod + 252 23 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 24 AppKit 0x18f241770 forwardMethod + 252 25 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 26 AppKit 0x18f241770 forwardMethod + 252 27 AppKit 0x18f2e62a0 -[NSView scrollWheel:] + 408 28 AppKit 0x18f1d27b0 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 652 As you can see, there's no code of mine involved at the time of crash. The other (and older) reports are similar, in macOS 13.6.1 and macOS 13.1. All four happened on ARM architecture (which may not be significant due to small number of samples). Memory use of app was not critical (in one case it was about 9 GB total, in others below 4 GB). The "Binary Images" section only lists Apple libs, apart from my app's. So, there seems to be no 3rd party ext involved. I've attached a full report as well. Full report of Crash 1
Replies
2
Boosts
0
Views
1.3k
Activity
Mar ’26
How do you make a resizable segmented control in SwiftUI for macOS?
In SwiftUI for macOS, how do I configure a Picker as a segmented control to have a flexible width? This design pattern is present in Xcode 26 at the top of the sidebar and inspector panel. I can't figure out the combination of view modifiers to achieve a similar look. import SwiftUI struct ContentView: View { @State private var selection = 0 var body: some View { VStack { Picker("", selection: $selection) { Image(systemName: "doc") Image(systemName: "folder") Image(systemName: "gear") Image(systemName: "globe") .frame(maxWidth: .infinity) // Doesn't do anything. } .labelsHidden() .pickerStyle(.segmented) .frame(maxWidth: .infinity) // Doesn't affect segment sizes. Spacer() } } } I want the entire Picker to fill the width and for each segment to be of equal widths. How? In AppKit I would use AutoLayout for the flexible width and NSSegmentedControl.segmentDistribution for the segment widths. Is there a SwiftUI equivalent? macOS 26 / Xcode 26.3
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
0
Boosts
0
Views
97
Activity
Mar ’26
SwiftData with shared and private containers
I was hoping for an update of SwiftData which adopted the use of shared and public CloudKit containers, in the same way it does for the private CloudKit container. So firstly, a big request to any Apple devs reading, for this to be a thing! Secondly, what would be a sensible way of adding a shared container in CloudKit to an existing app that is already using SwiftData? Would it be possible to use the new DataStore method to manage CloudKit syncing with a public or shared container?
Replies
12
Boosts
18
Views
4.0k
Activity
Mar ’26
Active Quicklook extension is ignored
When you have multiple Apps on the Mac which all provide Quicklook extensions for the same file type, then I would assume that if I activate one of these Quicklook extensions in the system settings, this one would be used. But this doesn't seem to be the case. It looks like the macOS just looks the very first extension it can find for a certain file type, and if this Quicklook extension is switched off, the file can not be previewed anymore. The macOS just doesn't bother to look for the other existing quicklook extension for this file, even if this other is enabled. The only option right now to get this other extension to be used by the system would be to completely delete the first App, so its extension is deleted as well. Is this really the way how it is supposed to work? How can this be fixed? Can I tell my users something else than "just delete the other App"?
Replies
0
Boosts
0
Views
137
Activity
Mar ’26
Detect closing of tab (NSWindowTab) in WindowGroup
I have a SwiftUI app displaying tabbed windows (as NSWindowTab) in a WindowGroup: import SwiftUI @main struct TabTestApp: App { var body: some Scene { WindowGroup{ ContentView() // Hasn't any content of relevance to this question. }.commands{ CommandGroup(after: .newItem) { Button("New Tab") { guard let currentWindow = NSApp.keyWindow, let windowController = currentWindow.windowController else { return } windowController.newWindowForTab(nil) guard let newWindow = NSApp.keyWindow else { return } if currentWindow != newWindow { currentWindow.addTabbedWindow(newWindow, ordered: .above) } }.keyboardShortcut(.init("t", modifiers: [.command])) } } } } Is there a way to detect the closing of one or multiple tabs, e.g. when the user clicks on the tab bar's "Close Other Tabs" option or pushes CMD + W in order to ask the user whether he or she wants to save changes? What I've tried to no avail: Intercept windowWillClose👉Won't be called if a single tab within a window is closed (but only once the last tab of a window is closed). Handling onDissapear()👉Doesn't work since the closing cannot be cancelled. Using DocumentGroup 👉Doesn't work since the app in question isn't about documents (i.e., files which are stored externally), but about data that's stored in a database. Many thanks! Related threads: Preserve all tabs of last window on close. (Like Finder) Detect Close Window vs Close Tab
Replies
0
Boosts
0
Views
75
Activity
Mar ’26
Live Activity Blanks out when lock screen sleeps.
I have a live activity, that works fine when the Lock Screen showing, but as soon as it "sleeps" dims down for always on display, everything in the widget disappears and an Activity Indicator(spinner), displays in its place, but non-animating.
Replies
4
Boosts
0
Views
954
Activity
Feb ’26
UIScrollView Layout issue
I run into a layout problem where I cannot center an image inside ScrollView which is also inside Navigation Controller. The problem is surely the fact that there is a navigation bar because using this view without NavigationContoller works fine and the image is centered but I don’t know how to account for the space that navigation bar takes up. Here is the code: import UIKit class PhotoViewController: UIViewController { var photoName: String private lazy var photoView = { let image = UIImageView() image.translatesAutoresizingMaskIntoConstraints = false image.contentMode = .scaleAspectFit image.clipsToBounds = true return image }() var photoViewBottomConstraint: NSLayoutConstraint? var photoViewLeadingConstraint: NSLayoutConstraint? var photoViewTopConstraint: NSLayoutConstraint? var photoViewTrailingConstraint: NSLayoutConstraint? private lazy var scrollView = { let sv = UIScrollView() sv.translatesAutoresizingMaskIntoConstraints = false return sv }() override func viewDidLoad() { super.viewDidLoad() setupUI() } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() updateMinZoomScaleForSize(view.bounds.size) } func updateMinZoomScaleForSize(_ size: CGSize) { let widthScale = size.width / photoView.bounds.width let heightScale = size.height / photoView.bounds.height let minScale = min(widthScale, heightScale) scrollView.minimumZoomScale = minScale scrollView.zoomScale = minScale } func setupUI() { photoView.image = UIImage(named: photoName) scrollView.delegate = self view.addSubview(scrollView) scrollView.addSubview(photoView) setupConstraints() } func setupConstraints() { NSLayoutConstraint.activate([ scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) photoViewLeadingConstraint = NSLayoutConstraint( item: photoView, attribute: .leading, relatedBy: .equal, toItem: scrollView, attribute: .leading, multiplier: 1, constant: 0 ) photoViewTopConstraint = NSLayoutConstraint( item: photoView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1, constant: 0 ) photoViewTrailingConstraint = NSLayoutConstraint( item: photoView, attribute: .trailing, relatedBy: .equal, toItem: scrollView, attribute: .trailing, multiplier: 1, constant: 0 ) photoViewBottomConstraint = NSLayoutConstraint( item: photoView, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1, constant: 0 ) photoViewLeadingConstraint?.isActive = true photoViewTopConstraint?.isActive = true photoViewTrailingConstraint?.isActive = true photoViewBottomConstraint?.isActive = true } init(photoName: String) { self.photoName = photoName super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } extension PhotoViewController: UIScrollViewDelegate { func viewForZooming(in scrollView: UIScrollView) -> UIView? { photoView } func scrollViewDidZoom(_ scrollView: UIScrollView) { updateConstraintsForSize(view.bounds.size) } func updateConstraintsForSize(_ size: CGSize) { let yOffset = max(0, (size.height - photoView.frame.height) / 2) photoViewTopConstraint?.constant = yOffset photoViewBottomConstraint?.constant = yOffset let xOffset = max(0, (size.width - photoView.frame.width) / 2) photoViewLeadingConstraint?.constant = xOffset photoViewTrailingConstraint?.constant = xOffset view.layoutIfNeeded() } }
Replies
3
Boosts
0
Views
181
Activity
Feb ’26
UIActivityViewController not vertically scrollable when sharing CSV on specific device (Save option unreachable)
Platform UIKit iOS UIActivityViewController Environment Device (issue reported): iPhone 16 iOS Version: 26.2 App Type: UIKit / Swift (standard modal presentation of UIActivityViewController) Summary When presenting UIActivityViewController to share a CSV file, the share sheet does not allow vertical scrolling, making lower actions (including Save to Files) unreachable. The same flow works correctly when sharing a PDF, and the issue cannot be reproduced on other test devices. Steps to Reproduce Launch the app and log in Navigate to More → Reports Tap Export Report Choose Export Report (CSV) Observe the share sheet Expected Result The user should be able to vertically scroll the share sheet All share actions (including Save to Files) should be reachable Actual Result Share sheet opens but vertical scrolling is disabled Lower options (including Save to Files) are not reachable No crash or console errors
Replies
3
Boosts
0
Views
409
Activity
Feb ’26