Construct and manage a graphical, event-driven user interface for your macOS app using AppKit.

AppKit Documentation

Post

Replies

Boosts

Views

Activity

Crash on Intel during UI layout
We've got a hard to repro issue on Intel only when performing UI layout. It seems the collection view code gets into a recursive loop of doom and eventually the app crashes. This is only happening on Intel, the ARM version is fine. It seems related to this issue: https://developer.apple.com/forums/thread/732580 There an Apple Dev acknowledges that there are issues with the Intel version of the OS. Here's the simplified stack we're seeing: -[NSISEngine _coreReplaceMarker:withMarkerPlusDelta:]" -[NSISEngine constraintDidChangeSuchThatMarker:shouldBeReplacedByMarkerPlusDelta:]", -[NSISEngine tryToChangeConstraintSuchThatMarker:isReplacedByMarkerPlusDelta:undoHandler:]", -[NSLayoutConstraint _tryToChangeContainerGeometryWithUndoHandler:]", -[NSLayoutConstraint _setSymbolicConstant:constant:symbolicConstantMultiplier:]", -[NSLayoutConstraint setConstant:]", -[NSView(NSConstraintBasedLayoutInternal) _updateSimpleAutoresizingConstraintsInPlace:forAutoresizingMask:]", NSViewUpdateConstraintsForFrameChange -[NSView setFrameSize:]", -[NSView setFrame:]", -[NSClipView _updateOverhangSubviewsIfNeeded]", -[NSClipView _reflectDocumentViewFrameChange]", -[NSView _postFrameChangeNotification]"," -[NSView setFrameSize:]", -[NSCollectionView setFrameSize:]", -[NSView setFrame:]", NSViewActuallyUpdateFrameFromLayoutEngine", -[NSView resizeSubviewsWithOldSize:]", -[NSView setFrameSize:]", -[NSClipView setFrameSize:]", -[NSView setFrame:]", -[NSScrollView _setContentViewFrame:]", -[NSScrollView tile]", -[NSScrollView _tileWithoutRecursing]", -[NSScrollView reflectScrolledClipView:]", -[NSClipView _reflectDocumentViewFrameChange]_block_invoke", -[NSClipView _reflectDocumentViewFrameChange]", -[NSView _postFrameChangeNotification]", -[NSView setFrameSize:]", -[NSCollectionView setFrameSize:]", -[NSView setFrame:]", -[NSCollectionView _resizeToFitContentAndClipView]", -[_NSCollectionViewCore setContentSize:]", -[_NSCollectionViewCore _updateVisibleCellsNow:]" -[_NSCollectionViewCore _updateVisibleCellsNow:]" -[_NSCollectionViewCore _updateVisibleCellsNow:]" -[_NSCollectionViewCore _updateVisibleCellsNow:]" . . It seems to be limited to macOS 13.1 too. Hoping someone might have a clue? Thanks, Robert. Here's a link to the full stack: https://www.icloud.com/notes/076h1RXj4rvv7TzS5ICnvG6vw#NSCollectionView_crash_stack:
0
0
105
1w
Whats the Appkit equivalent of SwiftUI's NavigationSplitView?
How do I implement the same Navigation split view with a side bar in Appkit? Basically I have this code: import SwiftUI struct ContentView: View { var body: some View { NavigationSplitView { // Sidebar List { NavigationLink("Item 1", value: "Item 1 Details") NavigationLink("Item 2", value: "Item 2 Details") NavigationLink("Item 3", value: "Item 3 Details") } .navigationTitle("Items") } content: { // Main content (detail view for selected item) Text("Select an item to see details.") .padding() } detail: { // Detail view (for the selected item) Text("Select an item from the sidebar to view details.") .padding() } } } struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } and wanted to somehow convert it to Appkit. I tried to use an NSSplitViewController but I still don't have that side bar and that button to collapse it, how do I go about this?
2
0
156
1w
NSTextField Delegates Not Triggering After Refactoring NSView to NSViewController in macOS App
I'm developing a macOS application and facing an issue with NSTextField delegates after refactoring my code. Here's the situation: I have an NSWindowController. Inside the NSWindowController, there's a container NSView named containerView. On top of containerView, I added a custom NSView subclass named MyDetailsView. MyDetailsView has two NSTextField instances, and their delegates are properly set. The delegate methods like controlTextDidChange(_:) were getting called as expected. Due to some additional requirements, I refactored MyDetailsView into MyDetailsViewController, a subclass of NSViewController. I created a corresponding .xib file for MyDetailsViewController. Updated the code to load and add MyDetailsViewController's view (view property) to containerView. Verified that the NSTextField delegates are still being set, and the fields are displayed correctly in the UI. However, after this refactor, the NSTextField delegate methods (e.g., controlTextDidChange(_:)) are no longer being triggered. **What I've Tried: ** Verified that the delegates for the NSTextField instances are correctly set after the refactor. Ensured that the MyDetailsViewController's view is added to containerView. Question: What could be causing the NSTextField delegate methods to stop working after refactoring from NSView to NSViewController? @IBOutlet weak var customeView: NSView! var myDetailsViewController: MyDetailsViewController! var myDetailsView: MyDetailsView! var isViewController: Bool = true override func windowDidLoad() { super.windowDidLoad() if isViewController { myDetailsViewController = MyDetailsViewController(nibName: "MyDetailsViewController", bundle: nil) self.customeView.addSubview(myDetailsViewController.view) } else { myDetailsView = MyDetailsView.createFromNib() self.customeView.addSubview(myDetailsView!) } } override func showWindow(_ sender: Any?) { super.showWindow(nil) window?.makeKeyAndOrderFront(nil) } override var windowNibName: NSNib.Name? { return NSNib.Name("MyWindowController") }} class MyDetailsViewController: NSViewController { @IBOutlet weak var textField: NSTextField! override func viewDidLoad() { super.viewDidLoad() // Do view setup here. } } extension MyDetailsViewController: NSTextDelegate { func controlTextDidChange(_ obj: Notification) { guard let textField = obj.object as? NSTextField else { return } print("The value is ----> (MyDetailsViewController) \(textField.stringValue)") } } TextField delegate is set in XIB.
0
0
112
1w
Application terminates on sleep even if windows are not closed
I've received some reports from users of my macOS app that the application quits when putting their Mac to sleep after hiding all windows. The NSApplicationDelegate implements applicationShouldTerminateAfterLastWindowClosed and returns true. However this method is called even though there are still windows open. Unfortunately I'm not able to reproduce the issue, but here are the steps to reproduce according to the user: Open app (single NSWindow visible) Press Command-H to hide the single window Put Mac to sleep The app is terminated when the Mac wakes. These steps have been confirmed by a user in Safe Mode, so I expect no interference of other applications (macOS 15.1.1). When this happens the application logs show that applicationShouldTerminateAfterLastWindowClosed is called when the Mac goes to sleep. But the main NSWindow is still open (yet hidden). The close() method on NSWindow is not called before applicationShouldTerminateAfterLastWindowClosed. Order of events: NSApplicationDelegate.applicationWillHide NSApplicationDelegate.applicationWillResignActive [...] NSApplicationDelegate.applicationShouldTerminateAfterLastWindowClosed NSApplicationDelegate.applicationShouldTerminate NSApplicationDelegate.applicationWillTerminate NSWindow.close I assumed that applicationShouldTerminateAfterLastWindowClosed is only called after all windows are closed. Is that assumption incorrect? Does a user-hidden NSWindow count as a closed window? For me (and other users) the API works as expected and the app stays running when the app is hidden as the Mac sleeps. applicationShouldTerminateAfterLastWindowClosed is not called until all windows are actually closed.
1
1
116
2w
I Need Help!
I am trying to carry out repairs on my computer, it is an old MacBook Pro which I really appreciate, and it works very well, before attempting a hardware repair, I am exhausting all the software resources, in one of its support forums I found a supposed solution, I just can't see the assigned plist, but I see that it appears in the example as root within xcode, could you help me with what the steps would be to enter root mode and thus be able to make the relevant adjustment , I attach the link to the example. thank you so much https://discussions.apple.com/thread/3114550?sortBy=rank) The example can be found in Grant Bennet-Alder coment
1
0
136
2w
Screen record restriction in MacOS app
I have a MacOs AppKit app. This app we are developing for examination purposes. We dont want the user to screen record and also to take screen shot. We created a window and set the sharingType to none. also we have set window.level to CGShieldingWindowLevel() Below is the code if let window = NSApp.windows.first { window.title = "Test" window.sharingType = .none // Disable screen capture and recording window.level = NSWindow.Level(rawValue: Int(CGShieldingWindowLevel())) // } As per documentation the windows should be excluded from screen capture and also recording But the window is excluded only from screen capture and not from screen recording. Please give us a solution to prevent screen recording in MacOs native app.
3
0
170
3w
IKSaveOptions Only Calls its Delegate Once
I use IKSaveOptions to add an accessory view to an NSSavePanel to give the user choice of the image file type (etc) used to save a file. I limit the available file type choices in the accessory's menu by specifying a delegate object that offers the saveOptions:shouldShowUTType: method. Historically, my delegate was called repeatedly (for many file types) so, for those not supported by my code, I was able to omit them from the menu. This is expected behaviour from my interpretation of the documentation for saveOptions:shouldShowUTType: As of Ventura 13.1, the delegate was not called at all; instead, the entire (or at least a long) list of options was offered in the panel. Running the same build of my code on Catalina 10.15.7 still had the historical behaviour. In Sonoma (14.0) the delegate was called exactly once (for JPEG). This behaviour persists in Sequoia 15.1.1 . I have used test code and breakpoints to ensure that I pass a valid reference to my delegate and to inspect when (if) it is called. If there is some (new?) pre-condition for the accessory's use needed on Ventura and later, or a workaround, I would be grateful to be pointed to it.
0
0
148
3w
NSOutlineView with Diffable Data Source
Hi, On macOS, there seems to be a NSTableViewDiffableDataSource and an NSCollectionViewDiffableDataSource, but there seems to be nothing for NSOutlineView. Is it possible to somehow use NSTableViewDiffableDataSource with NSOutlineView that I'm missing? If not, is it possible to use NSTableView with NSTableViewDiffableDataSource to show a 'table' with section headers?
5
0
250
3w
Complex functions are not available
When I generate a dial through code, it prompts the following content: code: CLKWatchFaceLibrary * lib = [[CLKWatchFaceLibrary alloc] init]; [lib addWatchFaceAtURL:url completionHandler:^(NSError * _Nullable error) { }]; result: Complex functions are not available How to fix it? Make it usable, Thank you~
1
0
249
3w
Applying NSLayoutConstraints makes NSTableView unresponsive
In MacOS app I present modally NSTableView. The table is created in IB and its data and functionality are handled in corresponding NSViewController. As long as the positioning of modally presented table is left to the system, the tableview is placed in the center of the presenting view controller and everything works fine. But if I apply NSLayoutConstraints to position it as I need for visual design reasons, the table stops responding to mouse clicks. Here's the code inside the presenting view controller: bookmarks_TVC = Bookmarks_TVC() bookmarks_TVC.view.translatesAutoresizingMaskIntoConstraints = false self.present(bookmarks_TVC, animator: ModalPresentationAnimator()) NSLayoutConstraint.activate([ self.bookmarks_TVC.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant:410), self.bookmarks_TVC.view.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 170) ]) Once again, without NSLayoutConstraints the table responds as expected. Once the constraints are added, it becomes unresponsive. Thanks in advance for any helpful suggestions.
0
0
173
4w
Failure when setting file modificationDate
I properly copy a scrFile to a dstFile with mManager = [NSFileManager defaultManager]; [mManager copyItemAtPath:srcPath toPath:dstPath error:&error]; but on "some destination disks" the dstFile gets a modificationDate with truncated milliseconds. For instance, with this format "yyyy.MM.dd - HH:mm:ss:SSS" I visualize srcDate = 2024.11.03 - 12:42:35:772 dstDate = 2024.11.03 - 12:42:35:000 After the copyItemAtPath I even unsuccessfully tried to set the dstFile modificationDate this way NSMutableDictionary *dstAttrs = [NSMutableDictionary dictionaryWithDictionary:[mManager attributesOfItemAtPath:dstPath error:nil]]; [dstAttrs setObject:srcDate forKey:NSFileModificationDate]; [mManager setAttributes:dstAttrs ofItemAtPath:dstPath error:nil]; Again, the dstDate is 2024.11.03 - 12:42:35:000. I unsuccessfully tried even FSSetCatalogInfo(&dstRef, fsInfo, &srcFsCatInfo); No way. I noticed that the destination disk is an USB External Physical Volume, Mac OS Extended (Journaled) with "Ignore Ownership on this volume" on. Could this flag be the cause of the trouble? Shouldn't this flag regard only the files ownership? This issue brings another trouble. Since the srcDate and the dstDate are not equal, my macOS app performing a backup, copies the srcFile to the dstFile again and again. To workaround the trouble, I actually compare srcDate with dstDate after truncating their milliseconds. But I guess this is not a good practice. Any idea on how to fix this trouble? Thanks. P.S. I attach here the disk info Disk_Info.txt
2
0
286
Nov ’24
Changing the font size of a row - view-base tableview
So I'm following this code here where I'm using a tableview to display the files contained in a folder along with a group cell to display the name of the current folder: Here's my tableView:isGroupRow method: method which basically turns every row with the folder name into a group row (which is displayed in red in the previous image ). -(BOOL)tableView:(NSTableView *)tableView isGroupRow:(NSInteger)row { DesktopEntity *entity = _tableContents[row]; if ([entity isKindOfClass:[DesktopFolderEntity class]]) { return YES; } return NO; } and here's my tableView:viewForTableColumn:row: method where I have two if statements to decide whether the current row is a group row (meaning it's a folder) or an image: -(NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row; { DesktopEntity *entity = _tableContents[row]; if ([entity isKindOfClass:[DesktopFolderEntity class]]) { NSTextField *groupCell = [tableView makeViewWithIdentifier:@"GroupCell" owner:self]; [groupCell setStringValue: entity.name]; [groupCell setFont:[NSFont fontWithName:@"Arial" size:40]]; [groupCell setTextColor:[NSColor magentaColor]]; return groupCell; } else if ([entity isKindOfClass:[DesktopImageEntity class]]) { NSTableCellView *cellView = [tableView makeViewWithIdentifier:@"ImageCell" owner:self]; [cellView.textField setStringValue: entity.name]; [cellView.textField setFont:[NSFont fontWithName:@"Impact" size:20]]; [cellView.imageView setImage: [(DesktopImageEntity *)entity image]]; return cellView; } return nil; } Now, if the current row is an image, I change its font to Impact with a size of 40 and that works perfectly, the problem here is with the first IF statement, for a group row I wanted to change the font size to arial with a size of 40 with a magenta color but for some reason I can only get the color to work: You can see that my changes to the font size didn't work here, what gives? How can I change the font size for the group row ?
0
0
222
Nov ’24
How to drag and drop an image file to find in an app
import Cocoa @available(macOS 10.13, *) let imagePboardType = NSPasteboard.PasteboardType.fileURL class DragSourceView: NSImageView { weak var dragSourceDelegate: NSDraggingSource? override func mouseDown(with event: NSEvent) { //拖放数据定义 let pasteboardItem = NSPasteboardItem() //设置数据的Provider if #available(macOS 10.13, *) { pasteboardItem.setDataProvider(self, forTypes: [NSPasteboard.PasteboardType.fileURL]) } else { // Fallback on earlier versions } //拖放item let draggingItem = NSDraggingItem(pasteboardWriter: pasteboardItem) draggingItem.draggingFrame = NSRect(x: 100 , y: 10, width: 100, height: 100) //拖放可视化图象设置 draggingItem.imageComponentsProvider = { let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon) component.frame = NSRect(x: 0, y: 0, width: 16, height: 16) component.contents = NSImage(size: NSSize(width: 32,height: 32), flipped: false, drawingHandler: { [unowned self] rect in { self.image?.draw(in: rect) return true }() } ) return [component] } //开始启动拖放sesson self.beginDraggingSession(with: [draggingItem], event: event, source: self.dragSourceDelegate!) } } extension DragSourceView: NSPasteboardItemDataProvider { func pasteboard(_ pasteboard: NSPasteboard?, item: NSPasteboardItem, provideDataForType type: NSPasteboard.PasteboardType) { // let data = self.image?.tiffRepresentation let data = "/Users/slowdony/Desktop/640.jpeg" let dataUrl = data.data(using: String.Encoding(rawValue: NSUTF8StringEncoding))! item.setData(dataUrl, forType: type) } } import Cocoa class ViewController: NSViewController { @IBOutlet weak var sourceView: DragSourceView! override func viewDidLoad() { super.viewDidLoad() self.sourceView.dragSourceDelegate = self } } extension ViewController: NSDraggingSource { //返回拖放操作类型 func draggingSession(_ session: NSDraggingSession, sourceOperationMaskFor context: NSDraggingContext) -> NSDragOperation { if (context == .outsideApplication){ return .copy } else{ return .generic } } //开始拖放代理回调 func draggingSession(_ session: NSDraggingSession, willBeginAt screenPoint: NSPoint) { print("draggingSession beginAt \(screenPoint)") } //拖放鼠标移动时的代理回调 func draggingSession(_ session: NSDraggingSession, movedTo screenPoint: NSPoint) { print("draggingSession movedTo \(screenPoint)") } //结束拖放代理回调 func draggingSession(_ session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) { print("draggingSession endedAt \(screenPoint)") } } I am dragging an image to the desktop through the above code, failed, help
2
0
233
Nov ’24
NSToolbarItemGroup dynamically update subitems in toolbar
Developing on Monterey 12.7.5 I'm having trouble with updating subitems on NSToolbarItemGroup when selecting the item directly from the NSToolbar items array. I select the group item off the items array on the toolbar, and then call setSubitems: on the item, with a new array of NSToolbarItems. The group item disappears from the toolbar. It seems to leave a blank invisible item in the toolbar taking up space. I can't manually reinsert the item into the toolbar until I drag out the blank item, then drag back in the real item. Once dragged back in from the palette it displays correctly. The workaround I've come up with is to remove the item with NSToolbar removeItemAtIndex: and reinsert it with NSToollbar insertItemWithItemIdentifier:atIndex:. This works to update the subitems. Every other toolbar item property that I've tried has been able to update the item directly in the toolbar. It's only the group item's subitems that don't want to update correctly. Is there a correct way to do this that I'm missing? Calling [toolbar validateVisibleItems] didn't seem to help.
0
0
195
Nov ’24
Prevent macOS window.level floating from showing on all screens in a multi monitor setup?
I am using the window.level set to .floating as described here: https://developer.apple.com/documentation/appkit/nswindow/level The setting itself works okay. However, in a multi monitor setup, the floating window is appearing on both the screens. How can I prevent this? My users report that before macOS Sonoma, this used to not happen. Has this behaviour changed? How can I revert back to the old behaviour?
1
0
257
Nov ’24
I can't stand IOS 18 photos app
I made an account on this site for the sole reason to post this. I can not stand the IOS 18 photo app, to put it bluntly its sucks, it's made the app unusable. I was nice, I'd thought I'd give it a month or two but no, it still sucks. I wish I could uninstall IOS 18 solely cause of it. I hate the UI, its utterly unintuitive.
1
4
546
Nov ’24
Inconsistent "New York" font returned between devices
I'm seeing a discrepancy in the metrics of the "New York" system font returned from various Macs. Here's a sample (works well in Playgrounds): import Cocoa let font = NSFont(descriptor: .preferredFontDescriptor(forTextStyle: .body).withDesign(.serif)!, size: NSFont.systemFontSize)! print("\(font.fontName) \(font.pointSize)") print("ascender: \(font.ascender)") let layoutManager = NSLayoutManager() print("lineHeight: \(layoutManager.defaultLineHeight(for: font))") When I run this on multiple Macs, I get two types of different results. Some – most Macs – report this: .NewYork-Regular 13.0 ascender: 12.3779296875 lineHeight: 16.0 However, when I run on my own Mac (and also on the one of a colleague), I get this instead: .NewYork-Regular 13.0 ascender: 14.034145955454255 lineHeight: 19.0 It's clearly the same font in the same point size. Yet the font has different metrics, causing a layout manager to also compute a significantly different line height. So far I've found out that neither CPU generation/architecture nor macOS version seem to play a role. This issue has been reproducible since at least macOS 14. Having just migrated to a new Mac, the issue is still present. This does not affect any other system or commonly installed font. It's only New York (aka the serif design). So I assume this must be something with my setup. Yet I have been unable to find anything that may cause this. Anybody have some ideas? Happy to file a bug report but wanted to check here first.
2
0
308
Nov ’24
Crash when setting up the content view loaded from a NIB
I am trying to understand why I am seeing crash reports for my code that creates a view from a NIB like the code below. The crash occurs when referencing contentView which should have been bound when the NIB was loaded. Am I missing something here other than checking the result of the loadNibNamed function call? class MyView: NSView { @IBOutlet var contentView: NSView! init() { super.init(frame: NSRect(x: 0, y: 0, width: 84.0, height: 49.0)) commonInit() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func commonInit() { Bundle.main.loadNibNamed("MyView", owner: self, topLevelObjects: nil) translatesAutoresizingMaskIntoConstraints = false contentView.translatesAutoresizingMaskIntoConstraints = false addSubview(contentView) contentView.frame = self.bounds }
6
0
441
Nov ’24