My app displays some text that should appear the same regardless of the container view or window size, i.e. it should grow and shrink with the container view or window.
On iOS there is UILabel.adjustsFontSizeToFitWidth but I couldn't find any equivalent API on macOS. On the internet some people suggest to iteratively set a smaller font size until the text fits the available space, but I thought there must be a more efficient solution. How does UILabel.adjustsFontSizeToFitWidth do it?
My expectation was that setting a font's size to a fraction of the window width or height would do the trick, but when resizing the window I can see a slightly different portion of it.
class ViewController: NSViewController {
override func loadView() {
view = MyView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
NSLayoutConstraint.activate([view.widthAnchor.constraint(equalTo: view.heightAnchor, multiplier: 3), view.heightAnchor.constraint(greaterThanOrEqualToConstant: 100)])
}
}
class MyView: NSView {
let textField = NSTextField(labelWithString: String(repeating: "a b c d e f g h i j k l m n o p q r s t u v w x y z ", count: 2))
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
textField.translatesAutoresizingMaskIntoConstraints = false
textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
addSubview(textField)
NSLayoutConstraint.activate([textField.topAnchor.constraint(equalTo: topAnchor), textField.leadingAnchor.constraint(equalTo: leadingAnchor), textField.trailingAnchor.constraint(equalTo: trailingAnchor)])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func resize(withOldSuperviewSize oldSize: NSSize) {
// textField.font = .systemFont(ofSize: frame.width * 0.05)
textField.font = .systemFont(ofSize: frame.height * 0.1)
}
}
AppKit
RSS for tagConstruct and manage a graphical, event-driven user interface for your macOS app using AppKit.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
(Using macOS 26 Beta 9 and Xcode 26 Beta 7) I am trying to support basic onDrop from a source app to my app. I am trying to get the closest "source" representation of a drag-and-drop, e.g. a JPEG file being dropped into my app shouldn't be converted, but stored as a JPEG in Data. Otherwise, everything gets converted into TIFFs and modern iPhone photos get huge. I also try to be a good app, and provide asynchronous support.
Alas, I've been running around for days now, where I can now support Drag-and-Drop from the Finder, from uncached iCloud files with Progress bar, but so far, drag and dropping from Safari eludes me.
My code is as follows for the onDrop support:
Image(nsImage: data.image).onDrop(of: Self.supportedDropItemUTIs, delegate: self)
The UTIs are as follows:
public static let supportedDropItemUTIs: [UTType] = [
.image,
.heif,
.rawImage,
.png,
.tiff,
.svg,
.heic,
.jpegxl,
.bmp,
.gif,
.jpeg,
.webP,
]
Finally, the code is as follows:
public func performDrop(info: DropInfo) -> Bool {
let itemProviders = info.itemProviders(for: Self.supportedDropItemUTIs)
guard let itemProvider = itemProviders.first else {
return false
}
let registeredContentTypes = itemProvider.registeredContentTypes
guard let contentType = registeredContentTypes.first else {
return false
}
var suggestedName = itemProvider.suggestedName
if suggestedName == nil {
switch contentType {
case UTType.bmp: suggestedName = "image.bmp"
case UTType.gif: suggestedName = "image.gif"
case UTType.heic: suggestedName = "image.heic"
case UTType.jpeg: suggestedName = "image.jpeg"
case UTType.jpegxl: suggestedName = "image.jxl"
case UTType.png: suggestedName = "image.png"
case UTType.rawImage: suggestedName = "image.raw"
case UTType.svg: suggestedName = "image.svg"
case UTType.tiff: suggestedName = "image.tiff"
case UTType.webP: suggestedName = "image.webp"
default: break
}
}
let progress = itemProvider.loadInPlaceFileRepresentation(forTypeIdentifier: contentType.identifier) { url, _, error in
if let error {
print("Failed to get URL from dropped file: \(error)")
return
}
guard let url else {
print("Failed to get URL from dropped file!")
return
}
let queue = OperationQueue()
queue.underlyingQueue = .global(qos: .utility)
let intent = NSFileAccessIntent.readingIntent(with: url, options: .withoutChanges)
let coordinator = NSFileCoordinator()
coordinator.coordinate(with: [intent],
queue: queue) { error in
if let error {
print("Failed to coordinate data from dropped file: \(error)")
return
}
do {
// Load file contents into Data object
let data = try Data(contentsOf: intent.url)
Dispatch.DispatchQueue.main.async {
self.data.data = data
self.data.fileName = suggestedName
}
} catch {
print("Failed to load coordinated data from dropped file: \(error)")
}
}
}
DispatchQueue.main.async {
self.progress = progress
}
return true
}
For your information, this code is at the state where I gave up and sent it here, because I cannot find a solution to my issue.
Now, this code works everywhere, except for dragging and dropping from Safari.
Let's pretend I go to this web site:
https://commons.wikimedia.org/wiki/File:Tulip_Tulipa_clusiana_%27Lady_Jane%27_Rock_Ledge_Flower_Edit_2000px.jpg
and I try to drag-and-drop the image, it will fail with the following error:
URL https://upload.wikimedia.org/wikipedia/commons/c/cf/Tulip_Tulipa_clusiana_%27Lady_Jane%27_Rock_Ledge_Flower_Edit_2000px.jpg is not a file:// URL.
And then, fail with the dreaded
Failed to get URL from dropped file: Error Domain=NSItemProviderErrorDomain Code=-1000
As far as I can tell, the problem lies in the opaque NSItemProvider receiving a web site URL from Safari. I tried most solutions, I couldn't retrieve that URL. The error happens in the callback of loadInPlaceFileRepresentation, but also fails in loadFileRepresentation. I tried hard-requesting a loadObject of type URL, but there's only one representation for the JPEG file. I tried only putting .url in the requests, but it would not transfer it.
Anyone solved this mystery?
Is there a way to access an Icon Composer .icon file in Swift or Objective-C? Any way to get this in an NSImage object that I can display in an image view? Thanks.
Hi everyone,
I'm encountering a behaviour related to Secure Event Input on macOS and wanted to understand if it's expected or if there's a recommended approach to handle it.
Scenario:
App A enables secure input using EnableSecureEventInput().
While secure input is active, App A launches App B using NSWorkspace or similar.
App B launches successfully, but it does not receive foreground focus — it starts in the background.
The system retains focus on App A, seemingly to preserve the secure input session.
Observed Behavior:
From what I understand, macOS prevents app switching during Secure Event Input to avoid accidental or malicious focus stealing (e.g., to prevent UI spoofing during password entry). So:
Input focus remains locked to App A.
App B runs but cannot become frontmost unless the secure input session ends or App B is brought to the frontmost by manual intervention or by running a terminal script.
This is consistent with system security behaviour, but it presents a challenge when App A needs to launch and hand off control to another app.
Questions:
Is this behaviour officially documented anywhere?
Is there a recommended pattern for safely transferring focus to another app while Secure Event Input is active?
Would calling DisableSecureEventInput() just before launching App B be the appropriate (and safe) solution? Or is there a better way to defer the transition?
Thanks in advance for any clarification or advice.
We are encountering an issue with noticeable lag when interacting with objects in Unity using the XR Interaction Toolkit. Even with the Movement Type set to Instantaneous, interactable objects still show a delay when following hand movements, especially at higher speeds.
Is there additional configuration required, or any recommended steps to eliminate this latency? https://wifi4compressed.com/
Topic:
UI Frameworks
SubTopic:
AppKit
I have a document-based macOS app written in Objective-C, and each document window contains a scrollable NSTextView. I know that printing can get complicated if you want to do nice pagination, but is there a quick and dirty way to get basic printing working? As it is, the print panel shows up, but its preview area is totally blank. Here's the current printing part of my NSDocument subclass.
- (NSPrintInfo *)printInfo
{
NSPrintInfo *printInfo = [super printInfo];
[printInfo setHorizontalPagination: NSPrintingPaginationModeFit];
[printInfo setHorizontallyCentered: NO];
[printInfo setVerticallyCentered: NO];
[printInfo setLeftMargin: 72.0];
[printInfo setRightMargin: 72.0];
[printInfo setTopMargin: 72.0];
[printInfo setBottomMargin: 72.0];
return printInfo;
}
- (void)printDocumentWithSettings:(NSDictionary<NSPrintInfoAttributeKey, id> *)printSettings
showPrintPanel:(BOOL)showPrintPanel
delegate:(id)delegate
didPrintSelector:(SEL)didPrintSelector
contextInfo:(void *)contextInfo
{
NSPrintInfo* thePrintInfo = [self printInfo];
[thePrintInfo setVerticallyCentered: NO ];
NSPrintOperation *op = [NSPrintOperation
printOperationWithView: _textView
printInfo: thePrintInfo ];
[op runOperationModalForWindow: _docWindow
delegate: delegate
didRunSelector: didPrintSelector
contextInfo: contextInfo];
}
We have an app that uses a NSProgressIndicator indeterminate and it no longer animates on Tahoe (currently beta 8). I did a empty swift app using storyboards and added this to the view controller:
override func viewDidLoad() {
super.viewDidLoad()
let progressIndicator=NSProgressIndicator.init(frame: NSMakeRect(0, 300, 400,20))
progressIndicator.style = .bar
progressIndicator.isIndeterminate = true
progressIndicator.isDisplayedWhenStopped=true
self.view.addSubview(progressIndicator)
progressIndicator.startAnimation(self)
}
Works fine in macOS 15, no animation in macOS 26. If I switch to the style to spinner, it animates fine.
Filed feedback FB19933934
Topic:
UI Frameworks
SubTopic:
AppKit
I have an NSSplitViewController with three columns:
sidebar
full-height content view with NSScrollView/NSTableView
detail view.
There's no (visible) titlebar and no toolbar.
This layout has worked fine for years, but in Tahoe an unwanted overlay (~30-50px high) appears at the top of any column containing a scroll view with table content. Xcode suggests it's an NSScrollPocket.
My research suggests it...
Only affects columns with NSScrollView
Plain NSView columns are unaffected
Overlay height varies (~50px or ~30px depending on how I mess with title / toolbar settings)
Disabling titlebar/toolbar settings reduces but doesn't eliminate the overlay
The overlay obscures content and there doesn't appear to be any API
to control its visibility. Is this intended behavior, and if so, is
there a way to disable it for applications that don't need this UI
element?
If it helps visualise the desired result, the app is https://indigostack.app
Any guidance would be appreciated!
Topic:
UI Frameworks
SubTopic:
AppKit
This method on UIEvent gets you more touch positions, and I think it's useful for a drawing app, to respond with greater precision to the position of the Pencil stylus.
Is there a similar thing in macOS, for mouse or tablet events? I found this property mouseCoalescingEnabled, but the docs there don't describe how to get the extra events.
Since macOS 26 Beta 1, I notice that the window reopening behavior had changed.
Say there are two desktops (spaces), one might:
open an app window in desktop 1
close that window
switch to desktop 2
reopen the app window (by click on dock tile, spotlight search...)
Prior to macOS 26, that window will always reopen in current desktop. This is IMO the right behavior because these windows are most likely transient (message app, chat app, utilities app or note app).
In macOS 26, however, will switch to desktop 1 (where the window is closed) and reopen the window in desktop 1.
This is weird to me because:
Window is "closed", hence it should not be attached to desktop 1 anymore, unlike minimize.
Switching desktop interrupts user's current workflow. It's annoying to switch back specially when there're many desktops.
This behavior is inconsistent. Some reopen in current desktop, some reopen in previous desktop. Apps like Music, Notes and Calendar reopened in previous desktop, while Mail, Messages, and Freeform reopened in current desktop.
I did a little bit of experiment, and find out that apps that reopened in current desktop are most likely because they take an extra step to release the window when it's closed.
I believe this is a bug, so I fire a feedback (FB18016497) back in beta 1. But I did not get any response or similar report from others, to a point that I kinda wonder if this is intended.
I can easily force my app to reopen in current desktop by nullifying my window controller in windowWillClose, but this behavior essentially change how one can use the Spaces feature that I think I should bring this up to the community and see what other developers or engineers thinks about it.
I have a standard Mac project created using Xcode templates with Storyboard. I manually removed the window from the Storyboard file and use ViewController.h as the base class for other ViewControllers. I create new windows and ViewControllers programmatically, implementing the UI entirely through code.
However, I've discovered that on all macOS versions prior to macOS 26 beta, the application would trigger automatic termination due to App Nap under certain circumstances. The specific steps are:
Close the application window (the application doesn't exit immediately at this point)
Click on other windows or the desktop, causing the application to lose focus (though this description might not be entirely accurate - the app might have already lost focus when the window closed, but the top menu bar still shows the current application immediately after window closure)
The application automatically terminates
In previous versions, I worked around this issue by manually executing [[NSApplication sharedApplication] run]; to create an additional main event loop, keeping the application active (although I understand this isn't an ideal approach).
However, in macOS 26 beta, I've found that calling [[NSApplication sharedApplication] run]; causes all NSButton controls I created in the window to become unresponsive to click events, though they still respond to mouse enter events.
Through recent research, I've learned that the best practice for preventing App Nap automatic termination is to use [[NSProcessInfo processInfo] disableAutomaticTermination:@"User interaction required"]; to increment the automatic termination reference count.
My questions are:
Why did calling [[NSApplication sharedApplication] run]; work properly on macOS versions prior to 15.6.1?
Why does calling [[NSApplication sharedApplication] run]; in macOS 26 beta cause buttons to become unresponsive to click events?
I implemented a subclass of NSCollectionViewItem:
class ViewItem: NSCollectionViewItem {
override func loadView() {
self.view = NSView()
}
}
and registed to NSCollectionView:
class PictureFrameThemeListView: NSCollectionView {
init(viewModel: PictureFrameViewModel) {
super.init(frame: .zero)
self.register(ViewItem.self, forItemWithIdentifier: .item)
}
However, when calling makeItem(withIdentifier:for:), the following error is prompted:
FAULT: NSInternalInconsistencyException: -[NSNib _initWithNibNamed:bundle:options:] could not load the nib 'Item' in bundle NSBundle
What confuses me is that I registered the subclass of NSCollectionViewItem, why do NSCollectionView to init the NSNib?
I have an app who's entire UI is a menu attached to a NSStatusIcon and after doing things in my app that largely work well, sometimes the icon is mysteriously vanishing from menu bar, its menu inaccessible.
I've seen it happen when launching normally, freshly built debug builds or release build installed from TestFlight, also launched from Xcode attached to lldb. In the latter case I can poke around in the state of the app but haven't been able to find any answers yet.
Things of note:
The menu bar icon isn't being removed in any normal fashion, it leaves an unnatural gap in the menu bar when my icon should be.
My app isn't crashing, hanging, or getting terminated: as evidenced by seeing it still running within Xcode. A part of my app that runs off a recurring timer responds normally to breakpoints.
The NSStatusIcon isn't getting released, its isVisible flag remains true, its button isn't going anywhere and neither is its button image.
Nothing interesting is logged to the Xcode console, I haven't found anything interesting in Console.app.
Does anyone know the state an app could get into that has this effect on its NSStatusIcon?
Topic:
UI Frameworks
SubTopic:
AppKit
I have a table view where each row has two labels, one left-aligned and one right-aligned. I would like to reload a single row, but doing so causes the right-aligned label to hug the left-aligned label.
Before the reload:
After the reload:
Reloading the whole table view instead, or disabling automatic row height, solves the issue. Can a single row be reloaded without resorting to these two workarounds?
I created FB13534100 1.5 years ago but got no response.
class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
override func loadView() {
let tableView = NSTableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.dataSource = self
tableView.delegate = self
tableView.usesAutomaticRowHeights = true
let column = NSTableColumn()
column.width = 400
tableView.addTableColumn(column)
let scrollView = NSScrollView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.documentView = tableView
view = scrollView
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { _ in
print("reload")
tableView.reloadData(forRowIndexes: IndexSet(integer: 2), columnIndexes: IndexSet(integer: 0))
// tableView.reloadData()
}
}
func numberOfRows(in tableView: NSTableView) -> Int {
return 5
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let cell = NSTableCellView()
let textField1 = NSTextField(labelWithString: "hello")
textField1.translatesAutoresizingMaskIntoConstraints = false
let textField2 = NSTextField(wrappingLabelWithString: "world")
textField2.translatesAutoresizingMaskIntoConstraints = false
textField2.alignment = .right
let stack = NSStackView(views: [
textField1,
textField2
])
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fill
cell.addSubview(stack)
NSLayoutConstraint.activate([stack.topAnchor.constraint(equalTo: cell.topAnchor, constant: 0), stack.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: 0), stack.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: 0), stack.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: 0)])
return cell
}
}
This example application crashes when entering any text to the token field with
FAULT: NSGenericException: 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.
The app uses controlTextDidChange to update a live preview where it accesses the objectValue of the token field.
If one character is entered, it also looks like the NSTokenFieldDelegate methods
tokenField(_:styleForRepresentedObject:) tokenField(_:editingStringForRepresentedObject:) tokenField(_:representedObjectForEditing:)
are called more than 10000 times until the example app crashes on macOS Tahoe 26 beta 6.
I've reported this issue with beta 1 as FB18088608, but haven't heard back so far.
I have multiple occurrences of this issue in my app, which is working fine on previous versions of macOS. I haven't found a workaround yet, and I’m getting anxious of this issue persisting into the official release.
Hello 👋
I'm playing with the Apple TextKit2 sample app (particularly on macOS).
I found that on some long document the evaluated height given by enumerateTextLayoutFragments API is wrong (or at least not I expect) which imply I can no longer scroll in my document even if I have not reached the end of it (which is not what I expect as you can guess). I'm clearly missing a point here. I can reproduce it on the Apple sample app by only changing the text content:
https://developer.apple.com/documentation/UIKit/using-textkit-2-to-interact-with-text
Using TextKit2, is it my responsability as developer to check that I've reached end of the scrollview whether not being at the end location of the document and call some specific TextKit2 API to invalidate estimation or something ?
Here is an updated version of the Apple sample app with another text content that show the issue.
https://drive.google.com/file/d/1jtTD84oqGAG4_A9DfqFl_yHmbLKhF1e8/view?usp=sharing
Environment: Xcode 16.4 - macOS 15.6
If someone could help me with this, I would be extremely grateful. It puzzles me.
NB: I've observed that resizing the window a bit seems to force a new layout and make TextKit2 returns a more accurate height, ... until you reach the end of the document.
I am developing an AppKit application in MacOS with Swift.
Our application requires a complex, multi-windowed interface and must deliver a very fast, responsive experience.
As a performance test, I built a sample app that creates 3 windows programmatically, each containing 500 NSTextFields (with each text-field assigned 35 different properties).
Code flow: https://gist.github.com/Raunit-TW/5ac58ac9c6584f93e2ee201aa8118139
This takes around 77 milliseconds to render the windows - I need to find a way to reduce this time, as low as possible.
Thanks.
NSToolbar items don’t react to Dark Mode changes in apps compiled with macOS 15 SDK:
My app was installed as a notarized app on a Tahoe VM with the same build as distributed in the App Store, based on macOS 15 SDK. When toggling Dark Mode, toolbar items are not updated, but only after opening a new window / tab or e.g. customizing the toolbar.
The app is using default methods for the toolbar, defined in its corresponding XIB file, and working in previous macOS versions. This issue could be confirmed with various apps built with an SDK prior to macOS 26 "Tahoe", e.g. Apple's Clipboard Viewer.
Reported via Feedback Assistent (FB19107572).
I have sadly not found any updated documentation regarding NSPasteboard or clipboard history in Spotlight on macOS Tahoe.
However...
It seems to support the standards outlined in NSPasteboard.org.
Here's my example code in macOS 26.0 Beta:
private func addPasswordToClipboardAsSimpleString() {
NSPasteboard.general.declareTypes([.string], owner: nil)
NSPasteboard.general.setString("Insecure password :(", forType:
.string)
}
private func addPasswordToClipboardAsNSPasteboardOrgString() {
NSPasteboard.general.declareTypes(
[
.string,
.init("org.nspasteboard.ConcealedType"),
.init("org.nspasteboard.TransientType")
],
owner: nil
)
NSPasteboard.general.setString(
"Secure password :)",
forType: .string
)
}
When calling addPasswordToClipboardAsSimpleString(), the string is always visible in clipboard history in spotlight.
When calling addPasswordToClipboardAsNSPasteboardOrgString(), the string is not visible in clipboard history in spotlight. Once the org.nspasteboard.* types are removed from the declaration, the item is visible in clipboard history.
Can someone from Apple confirm what the behavior of the clipboard history is regarding NSPasteboard.org standards? Or is there an official API to mark a confidential (e.g. password) item that I write to NSPasteboard.general not show up in Spotlight's clipboard history?
What are the SwiftUI equivalent of
NSSplitViewController.automaticallyAdjustsSafeAreaInsets
NSToolbarItem.style
These were introduced in the WWDC 2025 session named "Build an AppKit app with the new design". Jeff introduced only the AppKit API's while there was no mention of SwiftUI API