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

AppKit Documentation

Posts under AppKit subtopic

Post

Replies

Boosts

Views

Activity

NSCollectionLayoutBoundarySupplementaryItem background blur covering the entire layout section
My app has the following UI layout: NSSplitViewController as the windows contentViewController NSPageController in the content (right) split item NSTabViewController as the root items of the NSPageController NSViewController with a collection view in the first tab of that NSTabViewController The collection view is using a NSCollectionViewCompositionalLayout in which the sections are set up to have a header using NSCollectionLayoutBoundarySupplementaryItem with pinToVisibleBounds=true and alignment=top With macOS 26, the pinned supplementary item automatically gets a blurred/semi-transparent background that seamlessly integrates with the toolbar. When the window's title bar has a NSTitlebarAccessoryViewController added, the said semi-transparent background gets a bottom hard edge and a hairline to provide more visual separation from the main content. During runtime, my NSPageController transitions from the NSTabViewController to another view controller. When transitioning back, the semi-transparent blur bleeds into the entire section. This happens no matter if there's a NSTitlebarAccessoryViewController added or not. It doesn't happen 100% of the cases, it seems to depend on section size, header visibility and/or scroll position. But it happens more often than not. Most of the time, a second or so after the back transition - shortly after pageControllerDidEndLiveTransition: of the NSPageControllerDelegate is called - the view updates and the supplementary views are back to normal. Sometimes, the issue also appears not when transitioning using NSPageController, but simply by scrolling through the collection view. Anyone has an idea what is happening here? Below are two screenshots of both the "ok" and "not ok" state I'm on macOS 26.0.1 and I'm using XCode 26.0.1
Topic: UI Frameworks SubTopic: AppKit Tags:
3
0
120
1d
Incorrect menu consistency warnings logged in Tahoe for NSStatusItem, performance issues related?
Is anyone else getting new warning about menu items with submenus when running on Tahoe? I'm getting big performance problems using my menu as well as seeing these messages and I'm wondering if there's a connection. My app is faceless with a NSStatusItem with an NSMenu. Specifically it's my own subclass of NSMenu where I have a lot of code to manage the menu's dynamic behavior. This code is directly in the menu subclass instead of in a controller because the app I forked had it this way, a little wacky but I don't see it being a problem. A nib defines the contents of the menu, and it's instantiated manually with code like: var nibObjects: NSArray? = [] guard let nib = NSNib(nibNamed: "AppMenu", bundle: nil) else { ... } guard nib.instantiate(withOwner: owner, topLevelObjects: &nibObjects) else { ... } guard let menu = nibObjects?.compactMap({ $0 as? Self }).first else { ... } Within that nib.instantiate call I see a warning logged that seems new to Tahoe, before the menu's awakeFromNib is called, that says (edited): Internal inconsistency in menus - menu <NSMenu: 0x6000034e5340> believes it has <My_StatusItem_App.AppMenu: 0x7f9570c1a440> as a supermenu, but the supermenu does not seem to have any item with that submenu My_StatusItem_App.AppMenu: 0x7f9570c1a440 is my menu belonging to the NSStatusItem, NSMenu: 0x6000034e5340 is the submenu of one of its menu items. At a breakpoint in the NSMenu subclass's awakeFromNib I print self and see clear evidence of the warning's incorrectness. Below is a snippet of the console including the full warning, only edited for clarity and brevity. It shows on line 32 menu item with placeholder title "prototype batch item" that indeed has that submenu. Internal inconsistency in menus - menu <NSMenu: 0x6000034e5340> Title: Supermenu: 0x7f9570c1a440 (My StatusItem App), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( "<NSMenuItem: 0x6000010e4fa0 Do The Thing Again, ke mask='<none>'>", "<NSMenuItem: 0x6000010e5040 Customize\U2026, ke mask='<none>'>", "<NSMenuItem: 0x6000010e50e0, ke mask='<none>'>" ) believes it has <My_StatusItem_App.AppMenu: 0x7f9570c1a440> Title: My StatusItem App 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 (lldb) po self <My_StatusItem_App.AppMenu: 0x7f9570c1a440> Title: My StatusItem App Supermenu: 0x0 (None), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( "<NSMenuItem: 0x6000010fd7c0 About My StatusItem App\U2026, ke mask='<none>', action: showAbout:, action image: info.circle>", "<NSMenuItem: 0x6000010fd860 Show Onboarding Window\U2026, ke mask='Shift', action: showIntro:>", "<NSMenuItem: 0x6000010fd900 Update Available\U2026, ke mask='<none>', action: installUpdate:, standard image: icloud.and.arrow.down, hidden>", "<NSMenuItem: 0x6000010e46e0, ke mask='<none>'>", "<NSMenuItem: 0x6000010e4780 Start The Thing, ke mask='<none>', action: startTheThing:>", "<NSMenuItem: 0x6000010e4dc0 \U2318-\U232b key detector item, ke mask='<none>', view: <My_StatusItem_App.KeyDetectorView: 0x7f9570c1a010>>", "<NSMenuItem: 0x6000010e4e60, ke mask='<none>'>", "<NSMenuItem: 0x6000010e4f00 saved batches heading item, ke mask='<none>', view: <NSView: 0x7f9570b4be10>, hidden>", "<My_StatusItem_App.BatchMenuItem: 0x6000016e02c0 prototype batch item, ke mask='<none>', action: replaySavedBatch:, submenu: 0x6000034e5340 ()>", "<NSMenuItem: 0x6000010f7d40, ke mask='<none>'>", "<My_StatusItem_App.ClipMenuItem: 0x7f956ef14fd0 prototype copy clip item, ke mask='<none>', action: copyClip:>", "<NSMenuItem: 0x6000010fa620 Settings\U2026, ke='Command-,', action: showSettings:>", "<NSMenuItem: 0x6000010fa6c0, ke mask='<none>'>", "<NSMenuItem: 0x6000010fa760 Quit My StatusItem App, ke='Command-Q', action: quit:>" ) Is this seemingly incorrect inconsistency message harmless? Am I only grasping at straws to think it has some connection to the performance issues with this menu?
1
0
101
2d
How do I have the NSToolbar "floating" on top of content scrollview on macOS Tahoe?
I have this MWE right here -- it has a toolbar with a random action on it, in addition to a scroll view as the content of the window, with random labels attached inside. Since the redeisgn of the NSToolbar stuff in Tahoe, I expect the share button be able to "float" on top of the scrolled out content as shown as the first image at https://developer.apple.com/documentation/TechnologyOverviews/adopting-liquid-glass. #import <Cocoa/Cocoa.h> @interface AppDelegate : NSObject <NSApplicationDelegate, NSToolbarDelegate> @property (strong) NSWindow *window; @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)notification { NSRect frame = NSMakeRect(100, 100, 600, 400); self.window = [[NSWindow alloc] initWithContentRect:frame styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable) backing:NSBackingStoreBuffered defer:NO]; [self.window setTitle:@"Scroll View + Toolbar Demo"]; NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"MainToolbar"]; toolbar.displayMode = NSToolbarDisplayModeIconAndLabel; toolbar.delegate = self; [self.window setToolbar:toolbar]; NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:self.window.contentView.bounds]; [scrollView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; [scrollView setHasVerticalScroller:YES]; [scrollView setHasHorizontalScroller:YES]; NSView *documentView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 1000, 1000)]; for (int i = 0; i < 10; i++) { NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(50, 950 - i*80, 400, 40)]; [label setStringValue:[NSString stringWithFormat:@"Sample Label #%d", i + 1]]; [label setBezeled:NO]; [label setDrawsBackground:NO]; [label setEditable:NO]; [label setSelectable:NO]; [documentView addSubview:label]; } [scrollView setDocumentView:documentView]; [self.window setContentView:scrollView]; [self.window makeKeyAndOrderFront:nil]; } - (NSArray<NSToolbarItemIdentifier> *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar { return @[NSToolbarFlexibleSpaceItemIdentifier, @"ShareItem"]; } - (NSArray<NSToolbarItemIdentifier> *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar { return @[@"ShareItem"]; } - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSToolbarItemIdentifier)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag { if ([itemIdentifier isEqualToString:@"ShareItem"]) { NSToolbarItem *shareItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier]; shareItem.toolTip = @"Share this content"; shareItem.image = [NSImage imageNamed:NSImageNameShareTemplate]; shareItem.target = self; shareItem.action = @selector(shareAction:); return shareItem; } return nil; } - (void)shareAction:(id)sender { NSLog(@"Share button clicked!"); // Here you could present a sharing service picker NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:@[@"Hello, world!"]]; [picker showRelativeToRect:[sender view].bounds ofView:[sender view] preferredEdge:NSRectEdgeMinY]; } @end int main(int argc, const char * argv[]) { @autoreleasepool { NSApplication *app = [NSApplication sharedApplication]; AppDelegate *delegate = [[AppDelegate alloc] init]; [app setDelegate:delegate]; [app run]; } return EXIT_SUCCESS; } But it doesn't and produces this image: https://imgur.com/a/kA7MzIe I've tried to set various settings to make the top bar transparent, but all it does is that it makes it completely opaque instead. How can I make the share button float on top of the content? P.S. the app is a single-file app, compile it with clang -fobjc-arc -framework Cocoa -o ScrollApp toolbar.m
Topic: UI Frameworks SubTopic: AppKit
1
0
61
2d
NSScrollView only scrolls vertically for NSTableView after window resize
Hi everyone, I’m looking for help with an issue where using insertRows to add a row to an NSTableView requires resizing the window before I can scroll to the newly added rows that extend beyond the visible area of the NSScrollView. import Cocoa class ViewController: NSViewController { var data = Constants.movies // Table components var titleField = NSTextField() var directorField = NSTextField() var releaseYearField = NSTextField() var addMovieButton = NSButton(title: "Add Movie", image: NSImage(systemSymbolName: "plus", accessibilityDescription: "")!, target: nil, action: #selector(addMovie)) var table = NSTableView() var titleColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(Constants.titleColumnId)) var directorColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(Constants.directorColumnId)) var releaseYearColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(Constants.releaseColumnId)) // Scroll view let scrollView = NSScrollView() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. view.wantsLayer = true view.layer?.backgroundColor = NSColor.black.cgColor configure() } private func configure() { titleField.translatesAutoresizingMaskIntoConstraints = false directorField.translatesAutoresizingMaskIntoConstraints = false releaseYearField.translatesAutoresizingMaskIntoConstraints = false addMovieButton.translatesAutoresizingMaskIntoConstraints = false scrollView.translatesAutoresizingMaskIntoConstraints = false table.translatesAutoresizingMaskIntoConstraints = false titleField.placeholderString = "Movie Title" directorField.placeholderString = "Name of Director" releaseYearField.placeholderString = "Year Released" // Configure table table.addTableColumn(titleColumn) table.addTableColumn(directorColumn) table.addTableColumn(releaseYearColumn) titleColumn.title = "Movie Title" directorColumn.title = "Director" releaseYearColumn.title = "Year Released" table.delegate = self table.dataSource = self table.focusRingType = .none // Configure scroll view scrollView.documentView = table scrollView.hasVerticalScroller = true scrollView.hasHorizontalScroller = false scrollView.autohidesScrollers = true // Add views to the hierarchy view.addSubview(titleField) view.addSubview(directorField) view.addSubview(releaseYearField) view.addSubview(addMovieButton) view.addSubview(scrollView) // view.addSubview(table) NSLayoutConstraint.activate([ titleField.widthAnchor.constraint(equalToConstant: 150), directorField.widthAnchor.constraint(equalToConstant: 150), releaseYearField.widthAnchor.constraint(equalToConstant: 150), addMovieButton.widthAnchor.constraint(equalToConstant: 100), titleField.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), directorField.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), releaseYearField.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), addMovieButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), directorField.trailingAnchor.constraint(equalTo: view.centerXAnchor, constant: -10), releaseYearField.leadingAnchor.constraint(equalTo: view.centerXAnchor, constant: 10), titleField.trailingAnchor.constraint(equalTo: directorField.leadingAnchor, constant: -20), addMovieButton.leadingAnchor.constraint(equalTo: releaseYearField.trailingAnchor, constant: 20), scrollView.topAnchor.constraint(equalTo: titleField.bottomAnchor, constant: 20), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20), scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20), // table.widthAnchor.constraint(equalTo: scrollView.contentView.widthAnchor), // table.heightAnchor.constraint(equalTo: scrollView.contentView.heightAnchor) ]) } @objc private func addMovie() { let title = titleField.stringValue let director = directorField.stringValue guard let year = Int(releaseYearField.stringValue) else { return } let movie = Movie(title: title, director: director, releaseYear: year) data.append(movie) // Approach 1 // table.reloadData() // Approach 2 let newRow = data.count - 1 table.insertRows(at: IndexSet(integer: newRow), withAnimation: .slideDown) } Using table.reloadData works fine and I can scroll to the new rows as I add them, but it doesn't have the smooth animation I want to achieve. What is the best practice and correct way for using table.insertRows to avoid this issue? Note: I am using programmatic constraints only.
1
0
43
5d
What is the standard process of subclassing NSTextLocation?
Cannot find any guidance in the forums and Developer Doc, the WWDC session Meet TextKit2 says this protocol is served for any location type espacially useful when the underlying doc model is not linear. But when I try to subclass the NSTextLocation with my own type to define a more structured location rather than a linear one, also with my own NSTextContentManager subclass implementation, I keep receiving the system internal Location model like NSCountableTextLocation compare to my location which cause the app to crash. -[NSCountableTextLocation compare:] receiving unmatching type <MarkdownTK2.ChildIndexPathLocation: 0x9b2402aa0> In my own NSTextContentManager subclass: public override func offset( from: any NSTextLocation, to: any NSTextLocation ) -> Int { this method will also both receive my own location and some times receiving the system defined location that I can not calculate the offset then just return zero. The doc only says If you provide your own implementation of the NSTextLocation protocol to manage locations in your content, subclass NSTextContentManager and implement your own storage object to support those locations. OS Development environment: Xcode 26.0, macOS 26.0 Run-time configuration: macOS 26.0
3
0
174
1w
Resizing text to fit available space
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) } }
Topic: UI Frameworks SubTopic: AppKit Tags:
12
0
285
1w
CMD+V is not working on Tahoe OS with runForModalWindow screen
After upgrading my OS to Tahoe OS , in my application observed that Cmd+V is not working only on runForModalWindow. But menu Edit->Paste and Right click Paste is working on the same screen. Other screens in the application have no issues with Cmd+V. Could you please help with this issue why Cmd+V is not working only in this screen. Thanks, Sowmya
Topic: UI Frameworks SubTopic: AppKit
1
2
62
1w
How to bind AppKit window to Observable viewmodel using SwiftUI app life cycle
Hey everyone. I have a macOS app written in SwiftUI. I have multiple SwiftUI Scenes and Views, but needed to write one specific window in AppKit (an NSPanel, to be specific). The problem I'm facing is- I'm not sure how to incorporate this NSPanel with the rest of my SwiftUI/Observable code. I'm relying on the SwiftUI app cycle. For example, I have a boolean in my view model (observation tracked). I'd like to use this boolean to hide/unhide my NSPanel. Any way to cleanly hook into the viewmodel, or onto some specific observable variables would be very very helpful. Thank you everyone.
1
0
149
1w
[NSEvent charactersByApplyingModifiers:] not matching NSEvent.characters/charactersIgnoringModifiers
To my surprise [NSEvent charactersByApplyingModifiers:] does not always produce the same NSString result as the originating NSEvent reflects through characters/charactersIgnoringModifiers, even if passing on the event's own modifierFlags. For example, when pressing the 'end' key, both characters and charactersIgnoringModifiers return 0x000000000000f72b, which matches the value of NSEndFunctionKey. But calling [NSEvent charactersByApplyingModifiers:] passing in NSEvent.modifierFlags produces 0x0000000000000004, which matches the value of kEndCharCode. (lldb) po [[((NSApplication*)NSApp).currentEvent characters] characterAtIndex:0] 0x000000000000f72b (lldb) po [[((NSApplication*)NSApp).currentEvent charactersIgnoringModifiers] characterAtIndex:0] 0x000000000000f72b (lldb) po [[((NSApplication*)NSApp).currentEvent charactersByApplyingModifiers:[(NSEvent*)((NSApplication*)NSApp).currentEvent modifierFlags]] characterAtIndex:0] 0x0000000000000004 (The same can be observed with UCKeyTranslate directly, which charactersByApplyingModifiers seems to use internally). I would expect [NSApp.currentEvent charactersByApplyingModifiers:NSApp.currentEvent.modifierFlags] to match either NSApp.currentEvent.characters or NSApp.currentEvent.charactersIgnoringModifiers. Is there a logic behind this perceived discrepancy that I'm missing? Should I always prefer the content of NSEvent.characters/charactersIgnoringModifiers in this case if the modifier flags I'm applying match those of the event itself? Thanks for any insights! (Also reported as FB20591338)
Topic: UI Frameworks SubTopic: AppKit Tags:
3
0
78
2w
NSRulerView's background color and transparency (macOS 26)
When I compiled my legacy project with Tahoe's macOS 26 SDK, NSRulerViews are showing a very different design: Under prior macOS versions the horizontal and verrical ruler's background were blurring the content view, which was extending under the rulers, showing through their transparency. With Tahoe the horizontal ruler is always reflecting the scrollview's background color, showing the blurred content view beneath. And the vertical ruler is always completely transparent (without any blurring), showing the content together with the ruler's markers and ticks. It's difficult to describe, I'll try to replicate this behavior with a minimal test project, and probably file a bug report / enhancement request. But before I take next steps, can anyone confirm this observation? Maybe it is an intentional design decision by Apple?
3
0
142
2w
NSHostingSceneRepresentation doesn't show Window(_:id:) and UtilityWindow(_:id:) with .openWIndow(id:)
NSHostingSceneRepresentation, introduced in macOS 26, allows calling SwiftUI’s windows and other elements set in a Scene from AppKit. However, while Settings and WindowGroup set in the Scene can be invoked as expected using environment.openSettings() and environment.openWindow(id:) respectively, calling Window or WindowUtility doesn’t work. That is, the app just fails to open the desired window with the provided ID, and no error message or other feedback/crash/freeze appears. I expect that executing the openUtilityWindow(_:)action in the following code will display the UtilityWindow set in the scene. However, the window does not actually open. @main final class AppDelegate: NSObject, NSApplicationDelegate { private let scene = NSHostingSceneRepresentation { UtilityWindow("Utility Window", id: "UtilityWindow") { Text("Utility Window") .scenePadding() } } func applicationWillFinishLaunching(_ notification: Notification) { NSApp.addSceneRepresentation(self.scene) } @IBAction func openUtilityWindow(_ sender: Any?) { self.scene.environment.openWindow(id: "UtilityWindow") } } Is there something wrong with my implementation and expectation? Or is this a bug in NSHostingSceneRepresentation? Just in case, I’ve already filed this issue withFeedback Assistant: FB20310722 This feedback also includes a sample project reproducing this issue.
1
1
125
2w
What does it take for an app Window menu list to display the new items like Move & Resize?
Here's the result of a blank app from Xcode: https://imgur.com/a/1hMmwbO now there's only 3 items in the storyboard configuration: https://imgur.com/a/iGWWQE7 So I try to replicate that in code (some of this reproducer was generated by ChatGPT however the same issue I'm descrbing has been hit when using Python to objc bridges to construct the GUI) by specifying these 3 actions appropriately and see if the rest pops up. The code below changes the activation policy so that when I run ./a.out from the terminal it doesn't show as a window of Terminal but a separate app #import <Cocoa/Cocoa.h> @interface AppDelegate : NSObject <NSApplicationDelegate> @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)notification { // Build main menu NSMenu *mainMenu = [[NSMenu alloc] initWithTitle:@"MainMenu"]; // --- App menu with Quit --- NSMenuItem *appMenuItem = [[NSMenuItem alloc] init]; NSMenu *appMenu = [[NSMenu alloc] initWithTitle:@"App"]; NSMenuItem *quitItem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"]; [appMenu addItem:quitItem]; [appMenuItem setSubmenu:appMenu]; [mainMenu addItem:appMenuItem]; // --- Window menu with only Minimize, Zoom, Bring All to Front --- NSMenuItem *windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:NULL keyEquivalent:@""]; NSMenu *windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; [windowMenu addItem:[[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]]; [windowMenu addItem:[[NSMenuItem alloc] initWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]]; [windowMenu addItem:[NSMenuItem separatorItem]]; [windowMenu addItem:[[NSMenuItem alloc] initWithTitle:@"Bring All to Front" action:@selector(arrangeInFront:) keyEquivalent:@""]]; [windowMenuItem setSubmenu:windowMenu]; [mainMenu addItem:windowMenuItem]; [NSApp setMainMenu:mainMenu]; // Optional demo window (remove if you want zero windows) NSWindow *w = [[NSWindow alloc] initWithContentRect:NSMakeRect(200,200,400,200) styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable) backing:NSBackingStoreBuffered defer:NO]; [w setTitle:@"Demo"]; [w makeKeyAndOrderFront:nil]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { return YES; } @end int main(int argc, const char * argv[]) { @autoreleasepool { AppDelegate *delegate = [AppDelegate new]; [NSApplication sharedApplication]; [NSApp setDelegate:delegate]; return NSApplicationMain(argc, argv); } } Now, I only see 3 items that's literally specified https://imgur.com/a/LylRsaJ So, what allows interface builder to auto-add these extra items as opposed by creating it in code? Is there something in this reproducer of the Window menu that is missing that needs to make it happen programatically? Thanks! All tests done on macOS Tahoe
Topic: UI Frameworks SubTopic: AppKit
2
0
110
3w
PDFView Crash After Find Changing current selection and calling -scrollSelectionToVisible: on macOS Tahoe
Getting this crash after I do this in PDFKit a lot: PDFSelection *nextSelect = [self.pdfView.document findString:currentSearchString fromSelection:currentSelction withOptions:NSCaseInsensitiveSearch]; if (nextSelect != nil) { self.pdfView.currentSelection = nextSelect; [self.pdfView scrollSelectionToVisible:nil]; } Which often leads to: 0 CoreFoundation 0x000000019ced4770 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000019c9b2418 objc_exception_throw + 88 2 CoreFoundation 0x000000019cfffe10 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 724 3 CoreFoundation 0x000000019cfa1ae4 +[NSDictionary dictionaryWithObjects:forKeys:count:] + 52 4 PDFKit 0x00000001cb56e0fc -[PDFView _axPostPageChangeNotification:] + 348 5 Foundation 0x000000019e6a25e4 __NSFireDelayedPerform + 372 6 CoreFoundation 0x000000019ce92290 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 32 7 CoreFoundation 0x000000019ce91f50 __CFRunLoopDoTimer +
3
0
118
3w
NSScrollView scrolling hitch
When scrolling a basic NSScrollView there seems to be a sudden jump after each flick. Scrolling does not appear smooth and is disorientating. A scroll jump seems to happen directly after letting go of a scroll flick using a trackpad/mouse. Right at that moment the scroll turns into a momentum scroll, slowly decreasing the speed. But the first frame after the gesture the content jumps forward, more than what is expected. Observations: Counterintuitively, scrolling appears to be smoother when disabling NSScrollView.isCompatibleWithResponsiveScrolling. If disabled using a custom NSScrollView subclass there is no large jump anymore. Scrolling also appears to be smoother using a SwiftUI ScrollView. I assume that has the same behaviour as a disabled isCompatibleWithResponsiveScrolling Ironically a WKWebView scrolls much smoother. No sudden jump is observable. It also seems to scroll with faster acceleration, but the individual frames do appear smoother. Why is this better than a native NSScrollView? Elastic scrolling at the bounds of the scroll view also appears much smoother for WKWebViews. When pulling to refresh there is a jump for NSScrollView/SwiftUI, but not for WKWebView. When using an NSScrollView with isCompatibleWithResponsiveScrolling disabled, scrolling appears just as smooth as WKWebView on macOS 13 Ventura and below. On macOS 14 Sonoma scrolling behaviour is suddenly different. Please see a sample project with 4 different scroll views side by side: https://github.com/floorish/ScrollTest Screen recordings show the sudden jumps when scrolling and when elastic scrolling. Tested on Intel & Arm Macs, macOS 11 Big Sur through 15 Sequoia, built with Xcode 16. Should isCompatibleWithResponsiveScrolling be disabled on Sonoma+? Are there any drawbacks? There is also no overdraw anymore since Monterey, as described in https://developer.apple.com/library/archive/releasenotes/AppKit/RN-AppKitOlderNotes/#10_9Scrolling Even with responsive scrolling disabled, why is WKWebView scrolling much smoother than NSScrollView?
Topic: UI Frameworks SubTopic: AppKit Tags:
5
2
589
3w
AVPlayerViewController Mac Catalyst 26 Full Screen Crash
I have a SwiftUI Mac Catalyst app that shows a video player using a UIViewControllerRepresentable AVPlayerViewController. When I tap the full screen button on the native playback control, the app crashes. The app crashes only when built with Xcode 26. When I build with Xcode 16, this does not cause a crash. Here is some of the crash log: 0 CoreFoundation 0x000000019a5cc770 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000019a0aa418 objc_exception_throw + 88 2 CoreFoundation 0x000000019a69b7fc -[NSException initWithCoder:] + 0 3 AppKit 0x000000019eeee1d0 -[NSBezierPath(NSBezierPathDevicePrimitives) _deviceMoveToPoint:] + 104 4 AppKit 0x000000019eeec930 -[NSBezierPath appendBezierPathWithRoundedRect:xRadius:yRadius:] + 200 5 AppKit 0x000000019eeea238 +[NSBezierPath bezierPathWithRoundedRect:xRadius:yRadius:] + 88 6 AVKitMacHelper 0x0000000247d73cc4 -[AVScrubberSliderCell drawBarInside:flipped:] + 1264 7 AppKit 0x000000019f35cf7c -[NSSliderCell drawInteriorWithFrame:inView:] + 680 8 AppKit 0x000000019f35ccbc -[NSSliderCell drawWithFrame:inView:] + 104 Any ideas!?
0
0
89
3w
NSDocument doesn't autosave last changes
I had noticed an unsettling behaviour about NSDocument some years ago and created FB7392851, but the feedback didn't go forward, so I just updated it and hopefully here or there someone can explain what's going on. When running a simple document-based app with a text view, what I type before closing the app may be discarded without notice. To reproduce it, you can use the code below, then: Type "asdf" in the text view. Wait until the Xcode console logs "saving". You can trigger it by switching to another app and back again. Type something else in the text view, such as "asdf" on a new line. Quit the app. Relaunch the app. The second line has been discarded. Am I doing something wrong or is this a bug? Is there a workaround? class ViewController: NSViewController { @IBOutlet var textView: NSTextView! } class Document: NSDocument { private(set) var text = "" override class var autosavesInPlace: Bool { return true } override func makeWindowControllers() { let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil) let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController (windowController.contentViewController as? ViewController)?.textView.string = text self.addWindowController(windowController) } override func data(ofType typeName: String) throws -> Data { Swift.print("saving") text = (windowControllers.first?.contentViewController as? ViewController)?.textView.string ?? "" return Data(text.utf8) } override func read(from data: Data, ofType typeName: String) throws { text = String(decoding: data, as: UTF8.self) (windowControllers.first?.contentViewController as? ViewController)?.textView.string = text } }
Topic: UI Frameworks SubTopic: AppKit Tags:
17
0
412
3w
Window title bar in macOS 26 is drawn even if titlebarAppearsTransparent = true
macOS 26 sometimes draws the title bar background even when setting NSWindow.titlebarAppearsTransparent = true and I don't understand the logic behind it, or how I can turn this off. I'm trying to do something similar to Xcode's "Welcome to Xcode" window which has a left view and a right table view. In my simplified example, the window contains a label and a text view. This used to work in macOS 15, but in macOS 26 the text view is partially covered by the title bar: As soon as I remove the line scrollView.hasVerticalScroller = true, the title bar isn't drawn anymore: The title bar also isn't drawn when removing the view on the left of the text view: I created FB20341654. This may be related to this other issue: NSWindow.titlebarAppearsTransparent only works after collapsing and expanding sidebar @main class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { let window = NSWindow(contentViewController: ViewController()) window.titlebarAppearsTransparent = true window.titleVisibility = .hidden window.styleMask = [.titled, .closable, .fullSizeContentView] window.makeKeyAndOrderFront(nil) } } class ViewController: NSViewController { override func loadView() { view = NSView(frame: CGRect(x: 0, y: 0, width: 400, height: 200)) let scrollView = NSScrollView() scrollView.hasVerticalScroller = true // commenting this line out solves the issue scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.automaticallyAdjustsContentInsets = false let documentView = NSTextView() documentView.string = (0..<10).map({ "\($0)" }).joined(separator: "\n") scrollView.documentView = documentView let stack = NSStackView(views: [ NSTextField(labelWithString: "asdfasdfasdfasdf"), // commenting this line out also solves the issue scrollView ]) stack.orientation = .horizontal view.addSubview(stack) NSLayoutConstraint.activate([stack.topAnchor.constraint(equalTo: view.topAnchor), stack.leadingAnchor.constraint(equalTo: view.leadingAnchor), stack.trailingAnchor.constraint(equalTo: view.trailingAnchor), stack.bottomAnchor.constraint(equalTo: view.bottomAnchor)]) } }
Topic: UI Frameworks SubTopic: AppKit Tags:
2
0
155
3w