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

Posts under AppKit tag

183 Posts

Post

Replies

Boosts

Views

Activity

NSTokenField - How To Tell If I'm Editing an Existing Token in -tokenField:representedObjectForEditingString: ?
I'm trying to use NSTokenField for the first time. So my custom 'representedObject' for a token has additional model data tied to it (not just the editing/display string). I noticed when I edit an existing token, type text, and hit the enter key I get the following delegate callback: - (nullable id)tokenField:(NSTokenField *)tokenField representedObjectForEditingString:(NSString *)editingString; This same delegate method is called when I type a brand new token. Is there a way to distinguish if I'm editing a token vs. creating a new one? My expectation is to be able to do something like this (made up enhancement): - (nullable id)tokenField:(NSTokenField *)tokenField representedObjectForEditingString:(NSString *)editingString atIndex:(NSUInteger)existingTokenIndex { if (existingTokenIndex == NSNotFound) { // Token is new, create a new instance MyTokenObject *newToken = //create and configure. return newToken; } else { // This would update the editing string but wouldn't discard existing data held by the token. MyTokenObject *tokenObj = [self existingTokenAtIndex:existingTokenIndex]; tokenObj.editingString = editingString; return tokenObj; } }
0
0
26
1d
Does @IBSegueAction still not work for AppKit relationship segues from NSWindowController?
I’m working on a storyboard-based AppKit application that uses an NSWindowController containing an NSSplitViewController with multiple child view controllers. The hierarchy is roughly: NSWindowController └── NSSplitViewController ├── NSViewController ├── NSViewController └── NSViewController I am trying to provide dependencies during storyboard instantiation using either @IBSegueAction or instantiateInitialController(creator:), rather than configuring everything after initialisation. What I attempted I added custom initialisers to my view controllers so I can pass dependencies at creation time: class SplitViewController: NSSplitViewController { let dependency: Dependency init?(coder: NSCoder, dependency: Dependency) { self.dependency = dependency super.init(coder: coder) } required init?(coder: NSCoder) { print("init(coder:) was called") fatalError("init(coder:) is not supported") } } I then attempted to intercept storyboard instantiation using @IBSegueAction, trying it in both the window controller and the split view controller: @IBSegueAction func makeSplitViewController(_ coder: NSCoder) -> NSSplitViewController? { SplitViewController(coder: coder, dependency: dependency) } I also tried attaching the segue action at different points in the storyboard, but the behaviour did not change. Observed behaviour Regardless of where I place the segue action, AppKit still appears to call: required init?(coder: NSCoder) This means my custom initialiser is never used for the split view controller or its children. Background reference I found this older known issue in the Xcode 11 release notes: “A Segue Action on a relationship segue between a NSWindowController and a View Controller is currently not supported and ignored. (48252727)” This suggests that, at least historically, AppKit relationship segues ignored segue actions entirely. Has this limitation since been fixed in modern Xcode/macOS SDK releases, or are relationship segues involving NSWindowController still incompatible with @IBSegueAction? More generally, what is the intended way to provide dependencies to an NSSplitViewController and its child view controllers in a storyboard-based AppKit application? I am also unclear whether instantiateInitialController(creator:) participates in the creation of container hierarchies like split view controllers, or only top-level controllers.
0
0
122
4d
macOS 26: titlebar accessory can visually cover sidebar content with Reduce Transparency enabled
I’m seeing a macOS 26 AppKit issue with a sidebar + full-size content window + titlebar accessory setup. The main problem is that an NSTitlebarAccessoryViewController can visually cover the first item in the sidebar when System Settings > Accessibility > Display > Reduce Transparency is enabled. In my app this made the first sidebar/menu item look blacked out/covered by the titlebar/accessory area. While investigating possible workarounds, I also compared NSTitlebarAccessoryViewController with NSSplitViewItemAccessoryViewController and found two related issues that make the split-view accessory hard to use as a replacement. I could not attach the full sample project directly, so I included the two relevant Swift files below. The screenshots were taken from the same minimal AppKit repro with Reduce Transparency enabled. Repro setup The sample project shows: a fixed-width sidebar one content pane using NSTitlebarAccessoryViewController one content pane using NSSplitViewItemAccessoryViewController both accessories use the same custom view both custom views request the same intrinsic height each accessory displays its requested and actual height main.swift AppDelegate.swift Issue 1: titlebar accessory can cover sidebar content With Reduce Transparency enabled, the titlebar/accessory area can visually cover content at the top of the sidebar. This is the original issue I’m trying to solve. Expected: the sidebar content should not be covered by the titlebar accessory/material. Actual: the top sidebar item can appear blacked out/covered. In the first attached screenshot, "First sidebar row" is hidden/covered while "Second row" and the following rows are still visible. Issue 2: split-view accessory does not get the same hard separator As a possible workaround, I tried using NSSplitViewItemAccessoryViewController instead of NSTitlebarAccessoryViewController. Both controllers are configured with: if #available(macOS 26.1, *) { accessory.preferredScrollEdgeEffectStyle = .hard } The titlebar accessory shows the expected hard boundary/separator behavior, but the split-view item accessory does not appear to get the same hard edge treatment. The second attached screenshot shows the workaround comparison between the titlebar accessory and the split-view accessory. Expected: preferredScrollEdgeEffectStyle = .hard should produce a comparable hard separator for the split-view accessory. Actual: the split-view accessory still looks visually different and does not show the same hard boundary. Issue 3: split-view accessory is inset differently The NSSplitViewItemAccessoryViewController also appears to be laid out with spacing/insets around it. In the repro, the accessory custom view has a faint red background. Both accessory views request and receive the same height: requested 36 pt, actual 36.0 pt So the mismatch does not seem to be caused by the accessory view’s own intrinsic height. Instead, the split-view accessory appears to be hosted inside an inset container, with spacing around it, while the titlebar accessory is flush with the titlebar/content edge. Expected: if both accessories host the same view with the same intrinsic height, their effective placement should be comparable, or there should be a documented way to remove/control the split accessory insets. Actual: the split-view accessory is visually inset on multiple sides, making it unsuitable as a drop-in workaround for the titlebar accessory issue. The second attached screenshot also shows this: the split-view accessory has the same requested and actual height as the titlebar accessory, but it is still visually inset and does not align the same way. Question Is this expected behavior on macOS 26, especially with Reduce Transparency enabled? If so, what is the recommended AppKit approach for placing a filter/search accessory below the toolbar/titlebar without covering sidebar content, while still getting a hard separator and predictable layout?
Topic: UI Frameworks SubTopic: AppKit Tags:
1
0
228
1w
Challenges using SwiftUI views inside an NSToolbarItem
I'm trying to use SwiftUI views inside an NSToolbarItem, and I feel like I'm fighting the system. The goal is to create custom toolbar controls. I don't want AppKit or SwiftUI to recognize that there's a SwiftUI view in the toolbar and then try to style it automatically, which is what I think is happening. Consider this hierarchy: - NSToolbar - NSToolbarItem - view -> MyCustomNSView - addSubview(NSHostingView<CustomView>) So CustomView is inside an NSHostingView, which is inside an NSView, which is assigned to the .view property of an NSToolbarItem. For a while, I struggled to get this working at all because SwiftUI's layout metrics appeared to be affected by safe area insets. SwiftUI's ignoresSafeArea() only seemed to move the problem around. For now, I've disabled full-size content view, which I don't really need anyway. However, a SwiftUI Button or Menu still doesn't behave or style the way I would expect when placed inside an NSToolbarItem. They don't seem to honor many of the styling attributes or view modifiers that work elsewhere. Is there a way to tell AppKit to "ignore" the children of my NSToolbarItem and not apply toolbar-specific styling to them? Am I even correct in thinking that AppKit is recognizing a Button or Menu in the toolbar and forcibly applying styling to it? Previously, I tried implementing my "custom toolbar" entirely outside of NSToolbar, but then SwiftUI struggled with placing views under the transparent, non-existent toolbar. I'd appreciate any direction or hints here. It would be really nice to use SwiftUI for the controls I have in mind, but at the moment I can't get close to the result I'm aiming for.
0
0
119
1w
How do I get content to blur behind a floating input bar, like Mail, Messages and other native apps do?
I have a chat app with a floating composer pill (NSGlassEffectView) pinned to the bottom of my content area. Messages scroll behind it. The pill looks fine but content behind it is completely clear. Fully legible text showing through, no frosting at all. Mail, Messages, Notes all have this frosted look where content behind a floating bar is blurred enough that you can't read it. That's what I'm going for. My scroll view has wantsLayer = true. I tried hasVerticalScroller = true + scrollerStyle = .overlay based on a tip I saw in another thread. No change. Is NSGlassEffectView supposed to blur what's behind it, or is the frosting in Apple's apps coming from the scroll edge effect? If it's the scroll edge effect, is there any way to trigger it for a custom floating view at the bottom of a scroll view? I can't find any AppKit API for this. I also spent time trying this in SwiftUI using .glassEffect() on macOS. Same result, the material renders nearly clear with no way to control the frosting level via any public API. If I'm missing something obvious I'd love to know. I've been stuck on this one for a while. Thanks for any advice! I've attached photos of my input bar (clearly transparent) and Apple Messages, which has a style that I see all over iOS and Mac OS 26.
0
0
214
2w
NSTextView.shouldDrawInsertionPoint doesn't work with TextKit 2
The following code only ever causes shouldDrawInsertionPoint to be printed (no drawInsertionPoint), but even if that method returns false, the blinking insertion point is still drawn. On the other hand, with TextKit 1 it works as expected. Is there a way to hide the default insertion point in TextKit 2? My app draws its own. I've filed FB13684251. class TextView: NSTextView { override var shouldDrawInsertionPoint: Bool { print("shouldDrawInsertionPoint") return false } override func drawInsertionPoint(in rect: NSRect, color: NSColor, turnedOn flag: Bool) { print("drawInsertionPoint", flag) } } ``
Topic: UI Frameworks SubTopic: AppKit Tags:
11
0
635
2w
AppKit & State Restoration: Windows Auto Closing On App Quit Breaks State Restoration
I probably should know the answer to this but I don't, so I'll ask. When I enable state restoration and have like three windows open, and I quit the app (via Quit menu, not 'Stop In Xcode') the following happens: -NSApplication calls _closeForTermination on all the windows and this causes state restoration to fail to restore these open windows on next app launch. This behavior is not aligned with the behavior of apps like Mail. If I have two "Viewer Windows" open in Mail and I quit the app, when I relaunch the two viewer windows are restored. I can of course track this and write data to restore for these auto closed window myself but shouldn't there be an easy way to opt in to this behavior?
1
0
210
2w
After binding to NSBrowser indexPaths the browser assumes I'm using NSBrowserCell and calls unimplemented methods on my NSCell subclass
So after binding to NSBrowser selectionIndexPaths: https://developer.apple.com/library/archive/documentation/Cocoa/Reference/CocoaBindingsRef/BindingsText/NSBrowser.html this causes NSBrowser to do some weird stuff that seems completely unrelated to this particular binding. It starts calling NSBrowserCell methods on my cells but my cell is not a NSBrowserCell. My cell is actually a subclass of NSTextFieldCell. But NSBrowser starts sending setIsLeaf: (which I don't implement). In any case if I implement the -setLeaf: that solves that unrecognized selector, but now my cells don't draw titles. Not sure why binding to selectionIndexPaths causes this behavior? The cell stuff seems unrelated to this particular binding. I am of course using the newer but still pretty old item based APIs... do these bindings only support using NSMatrix? I do set the binding after calling -setCellClass: but makes no difference. I also just tried overriding -setSelectionIndexPaths: but NSBrowser does not use the setter.
2
0
239
2w
Overlay window above all windows, even when moving spaces
Hi! I would like to overlay a macOS application window above all windows, even when moving spaces or moving to a fullscreen app, similar in function to the DropOver app for macOS. What I have tried: Overwriting the default app delegate in SwiftUI and creating the NSWindow myself. Then setting the window.collectionBehavior to [.canJoinAllApplications, .canJoinAllSpaces, .fullScreenAuxiliary] and the window.level to .floating or .statusBar. This works for moving between Spaces, but still does not display above apps in fullscreen mode. I also registered a notification observer for NSWorkspace.activeSpaceDidChangeNotification, where I call window.orderFrontRegardless() to always have my window frontmost. Still not displaying above fullscreen apps. What am I missing to make this work? Best regards
2
0
178
3w
How do I make an editable NSTextField wrap inside an NSTableView cell?
Hi, I’m pretty new to AppKit and I’m trying to make an NSTextField inside an NSTableView both: Editable Multi-line / wrapping Right now, wrapping works fine until I set: tf.isEditable = true Then the text becomes a single line. How do I make it editable while still wrapping correctly? import AppKit final class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { let tableView = NSTableView() let text = String(repeating: "A", count: 500) override func viewDidLoad() { super.viewDidLoad() view = tableView tableView.addTableColumn(NSTableColumn()) tableView.usesAutomaticRowHeights = true tableView.dataSource = self tableView.delegate = self } func numberOfRows(in tableView: NSTableView) -> Int { 1 } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { let cell = NSTableCellView() let tf = NSTextField(wrappingLabelWithString: text) tf.lineBreakMode = .byCharWrapping if let tableColumn { tf.preferredMaxLayoutWidth = tableColumn.width } tf.isEditable = true // comment this out and wrapping works cell.addSubview(tf) tf.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tf.leadingAnchor.constraint(equalTo: cell.leadingAnchor), tf.trailingAnchor.constraint(equalTo: cell.trailingAnchor), tf.topAnchor.constraint(equalTo: cell.topAnchor), tf.bottomAnchor.constraint(equalTo: cell.bottomAnchor), ]) return cell } }
4
0
300
3w
SwiftUI + AppKit context menu wedges window-level mouse events when the menu's anchor view is deleted by the menu's own action
I'm on macOS 26.4 (SwiftUI + SwiftData + AppKit bridging). I have a SwiftUI canvas where each child view (a card) carries a per-card AppKit context menu via an NSViewRepresentable overlay (a small NSView subclass that overrides menu(for:) and returns an NSMenu whose items invoke a Swift closure). The closure for the "Delete" item removes the underlying model object. SwiftData mutates → SwiftUI re-emits the canvas → the card containing the menu's anchor NSView unmounts → that anchor NSView is removed from the AppKit view hierarchy. After this happens, the entire window's SwiftUI gestures stop receiving mouse events: pan, zoom, taps on a separate background Color view all go silent. The window's first responder ends up at the NSWindow itself. The wedge persists across switching to a sibling SwiftUI view in the same window (different SwiftData root), so the bad state is at the window/event-routing level, not in any one SwiftUI subtree. The wedge is reliably cleared by another right-click that successfully shows + dismisses any menu — strongly suggesting AppKit's menu/event-tracking cleanup is left in a half-finished state because the anchor view went away during the cleanup window. I've already verified: Switching from explicit NSMenu.popUpContextMenu(_:with:for:) to overriding menu(for:) does not change the behavior. Deferring the model deletion via DispatchQueue.main.async, asyncAfter (30 ms), or RunLoop.main.perform(inModes: [.default]) either doesn't help or only avoids the wedge if the delay is long enough to be perceptible (seconds), implying the cleanup window is event-driven, not time-driven. Triggering the same deletion from a SwiftUI Button (no AppKit menu involved) never wedges. My current understanding is that the standard AppKit pattern (e.g., NSTableView, NSOutlineView) attaches the context menu to a stable parent view, never to the per-row view itself, precisely so the menu's anchor outlives any single row's deletion. Restructuring my code so a single canvas-level AppKitContextMenuRegion returns the appropriate menu via hit-testing in menu(for:) should avoid the issue, but I'd like to confirm: Is the assumption that an NSMenu's anchor view must outlive the menu's tracking-end cleanup documented anywhere, or is it implicit? Is there a supported way to safely use a per-row anchor view that gets deleted by the menu's own action, or is the canvas-level / parent-level menu attachment the only correct pattern? 3. Are there any post-tracking notifications or APIs that guarantee AppKit's cleanup is complete before the anchor view is allowed to be torn down (so a per-row anchor could be made safe with the right ordering)? Thanks!
0
0
355
3w
NSCollectionView's 'selection box' freezes if you right-click during dragging
So in NSCollectionView I left click the background and start dragging to make the 'selection box' (is that what we call it?) I have a mouse with separate left and right click buttons (i.e., not an Apple Magic Mouse). Now if I accidentally hit the right click while I'm still dragging the selection box..... the right click context menu shows up in the middle of mouse dragging and the selection box freezes on screen. Besides the visual disruption this sometimes results in weird behavior. Sometimes mouse clicks stop responding for awhile in the window and I gotta click around a bunch of times until I guess the run loop "unclogs." I'm able to reproduce in Finder Icon view so it isn't just me. Steps to Reproduce: A mouse with separate buttons for left and right click. Open Finder window in icon view. Left click the background and start dragging to make the gray selection box. While dragging the mouse as you are selecting click right-click in the middle of the drag. The selection box freezes on screen. Expected Behavior: -Right click event and left mouse drag event normally shouldn't overlap. If left mouse is being dragged the right click event should be blocked. Let me know if this is Feedback worthy.
5
0
284
May ’26
How can I reliably get the final restored window size on macOS when onAppear / viewDidAppear fires too early?
I’m running into a macOS window restoration behavior issue where viewDidAppear (AppKit) or onAppear (SwiftUI) fires before the window’s final restored size is applied. AppKit example class MyViewController: NSViewController { override func viewDidLayout() { print("viewDidLayout: \(view.bounds.size)") } override func viewDidAppear() { print("viewDidAppear: \(view.bounds.size)") } } Logs on launch: viewDidAppear: (480.0, 270.0) viewDidLayout: (480.0, 270.0) viewDidLayout: (556.0, 476.0) viewDidLayout: (556.0, 476.0) The correct restored size is (556.0, 476.0), but viewDidAppear initially reports the old default size (480.0, 270.0). SwiftUI equivalent struct MyView: View { var body: some View { GeometryReader { geo in VStack {} .onAppear { print("onAppear: \(geo.size)") } .onChange(of: geo.size) { print("onChange: \(geo.size)") } } } } Logs on launch: onAppear: (900.0, 450.0) onChange: (680.0, 658.0) Problem I need to run some setup code: Only once After the view/window has its correct restored size Without rerunning on every layout or geometry change Question What is the proper macOS-native way to perform one-time startup logic only after the final restored window size is available? Is there a recommended lifecycle hook or pattern for this? Also, is it expected behavior that onAppear / viewDidAppear reports the pre-restoration size, or is it a bug?
3
0
362
May ’26
ScrollView/ClipView weirdness.
I have been playing around with AppKit programming and I have a sample document based app with a scroll view and rulers. When The scrollbars are not overlay style (which is usually true for me because I have "show scroll bars always" set in preferences) and the rulers are on The clip view seems to extend throughout the scroll view and the document can be seen through the scroll bars. However if I turn the rulers off, then the clip view seems to not include the scroll bars, and so the document is not visible through the scroll bars, having been clipped to the rectangle that lies inside the scroll bars. Additionally in this case, the small area in the lower right hand corner of the screen between the two scroll bars is white, even though all of my views have a light gray background. If the scroll bar style is overlay, then everything seems to work as expected: the clip view always includes the scroll bars. Is this a bug related to legacy style scrollbars or (more likely) have I just screwed something up? I should add that the window and the entire view hierarchy have been built programmatically. It is not in the xib.
Topic: UI Frameworks SubTopic: AppKit Tags:
1
0
422
May ’26
macOS main.swift and Main actor-isolated conformance cannot be used in nonisolated context
For a simple, resourceless cocoa apps I used to manually setup the application lifecycle (mimicking what's documented here: https://developer.apple.com/documentation/appkit/nsapplication), so my main.swift would look like: import Cocoa let delegate = SomeDelegate() _ = NSApplication.shared NSApp.delegate = delegate NSApp.run() This triggers a warning in Xcode 26.2: "Main actor-isolated conformance of SomeDelegate cannot be used in nonisolated context; this is an error in Swift 6 language mode". so what is the recommended way to refactor above so that it is Swift 6 compliant?
1
0
1.1k
Apr ’26
-applicationDockMenu: method on NSApplicationDelegate doesn't work when attached to debugger
When I add a simple menu to the dock via the NSApplicationDelegate method -applicationDockMenu: and run the app from Xcode it doesn't work. -(NSMenu*)applicationDockMenu:(NSApplication*)sender { NSMenu *dockMenu = [self buildDockMenu]; if (dockMenu != nil) { NSLog(@"Returning dock menu."); return dockMenu; } else { NSLog(@"Not ready to build dock menu"); return nil; } } When I run the app, my main app window shows up but nothing logs out in -applicationDockMenu: until I click outside my app's window (so if I click the desktop background, or a Finder window, or whatever). Then after I click outside my app's main window this logs out: Returning dock menu. The "Not ready to build dock menu" message does not log out. But...when I right click on the dock icon, the menu doesn't show up. But if I stop the app from Xcode and just run it not attached to the debugger, the dock menu does show up. But this makes the debugging/testing situation not ideal.
4
0
426
Apr ’26
NSOutlineView / NSTableView's Setting lineScroll to a somewhat absurd value of 304 in -tile
So I'm working on adding another component to my app that uses NSOutlineView, as we do in AppKit. There will probably always be less than 25 rows here. One row is much larger than the others. Not sure if any of this matters. What I know is I noticed scrolling it is very jank. It's going way too fast. So I took a peek and see lineScroll is getting is 304 in Interface Builder. Not sure how that happened. I changed it to like 24. Then Interface Builder automatically changes it back to 304. So in -viewDidLoad I just set it: NSScrollView *scrollView = self.outlineView.enclosingScrollView; scrollView.verticalLineScroll = 24.0; scrollView.lineScroll = 24.0; But scrolling still is busted. So I subclass NSScrollView and override the setters. For some reason, NSTableView's -tile method is deciding to change the lineScroll to 304, all on its own. So every time tile is called. line scrolls get reset to 304.
1
0
369
Apr ’26
AppKit - Legal to Change a View's Frame in -viewDidLayout?
I have (had) a view controller that does a bit of manual layout in a -viewDidLayout override. This was pretty easy to manage - however since introducing NSGlassEffectView into the view hierarchy I sometimes am getting hit with "Unable to simultaneously satisfy constraints" and Appkit would break a constraint to 'recover.' It appears translatesAutoresizingMaskIntoConstraints is creating some really weird fixed width and height constraints. Here I wasn't doing any autolayout - just add the glass view and set its frame in -viewDidLayout. At runtime since I do manual layout in -viewDidLayout the frames are fixed and there is no real "error" in my app in practice though I wanted to get rid of the constraint breaking warning being logged because I know Autolayout can be aggressive about 'correctness' who knows if they decide to throw and not catch in the future. In my perfect world I would probably just prefer a view.doesManualLayout = YES here - the subviews are big containers no labels so localization is not an issue for me. Rather than playing with autoresizing masks to get better translated constraints I decided to set translatesAutoresizingMaskIntoConstraints to NO and make the constraints myself. Now I get hit with the following exception: "The window has been marked as needing another Layout Window pass, but it has already had more Layout Window passes than there are views in the window" So this happens because the view which now has constraints -- I adjusted the frame of it one point in -viewDidLayout. My question is - is not legal to make changes in -viewDidLayout - which seems like the AppKit version of -viewDidLayoutSubviews. In UIKit I always thought it was fine to make changes in -viewDidLayoutSubviews to frames - even if constraints were used - this is a place where you could override things in complex layouts that cannot be easily described in constraints. But in AppKit if you touch certain frames in -viewDidLayout it can now cause this exception (also related: https://developer.apple.com/forums/thread/806471) I will change the constant of one of the constraints to account for the 1 point adjustment but my question still stands - is it not legal to touch frames in -viewDidLayout when autolayout constraints are used on that subview? It is (or at least was if I remember correctly) permitted to change the layout in -viewDidLayoutSubviews in UIKit but AppKit seems to be more aggressive in its checking for layout correctness). What about calling -sizeToFit on a control in viewDidLayout or some method that has side effect of invalidating layout in a non obvious way, is doing things like this now 'dangerous?' Shouldn't AppKit just block the layout from being invalidated from within -viewDidLayout - and leave whatever the layout is as is when viewDidLayout returns (thus making -viewDidLayout a useful place to override layout in the rare cases where you need a sledgehammer?)
4
0
763
Apr ’26
NSTokenField - How To Tell If I'm Editing an Existing Token in -tokenField:representedObjectForEditingString: ?
I'm trying to use NSTokenField for the first time. So my custom 'representedObject' for a token has additional model data tied to it (not just the editing/display string). I noticed when I edit an existing token, type text, and hit the enter key I get the following delegate callback: - (nullable id)tokenField:(NSTokenField *)tokenField representedObjectForEditingString:(NSString *)editingString; This same delegate method is called when I type a brand new token. Is there a way to distinguish if I'm editing a token vs. creating a new one? My expectation is to be able to do something like this (made up enhancement): - (nullable id)tokenField:(NSTokenField *)tokenField representedObjectForEditingString:(NSString *)editingString atIndex:(NSUInteger)existingTokenIndex { if (existingTokenIndex == NSNotFound) { // Token is new, create a new instance MyTokenObject *newToken = //create and configure. return newToken; } else { // This would update the editing string but wouldn't discard existing data held by the token. MyTokenObject *tokenObj = [self existingTokenAtIndex:existingTokenIndex]; tokenObj.editingString = editingString; return tokenObj; } }
Replies
0
Boosts
0
Views
26
Activity
1d
Does @IBSegueAction still not work for AppKit relationship segues from NSWindowController?
I’m working on a storyboard-based AppKit application that uses an NSWindowController containing an NSSplitViewController with multiple child view controllers. The hierarchy is roughly: NSWindowController └── NSSplitViewController ├── NSViewController ├── NSViewController └── NSViewController I am trying to provide dependencies during storyboard instantiation using either @IBSegueAction or instantiateInitialController(creator:), rather than configuring everything after initialisation. What I attempted I added custom initialisers to my view controllers so I can pass dependencies at creation time: class SplitViewController: NSSplitViewController { let dependency: Dependency init?(coder: NSCoder, dependency: Dependency) { self.dependency = dependency super.init(coder: coder) } required init?(coder: NSCoder) { print("init(coder:) was called") fatalError("init(coder:) is not supported") } } I then attempted to intercept storyboard instantiation using @IBSegueAction, trying it in both the window controller and the split view controller: @IBSegueAction func makeSplitViewController(_ coder: NSCoder) -> NSSplitViewController? { SplitViewController(coder: coder, dependency: dependency) } I also tried attaching the segue action at different points in the storyboard, but the behaviour did not change. Observed behaviour Regardless of where I place the segue action, AppKit still appears to call: required init?(coder: NSCoder) This means my custom initialiser is never used for the split view controller or its children. Background reference I found this older known issue in the Xcode 11 release notes: “A Segue Action on a relationship segue between a NSWindowController and a View Controller is currently not supported and ignored. (48252727)” This suggests that, at least historically, AppKit relationship segues ignored segue actions entirely. Has this limitation since been fixed in modern Xcode/macOS SDK releases, or are relationship segues involving NSWindowController still incompatible with @IBSegueAction? More generally, what is the intended way to provide dependencies to an NSSplitViewController and its child view controllers in a storyboard-based AppKit application? I am also unclear whether instantiateInitialController(creator:) participates in the creation of container hierarchies like split view controllers, or only top-level controllers.
Replies
0
Boosts
0
Views
122
Activity
4d
macOS 26: titlebar accessory can visually cover sidebar content with Reduce Transparency enabled
I’m seeing a macOS 26 AppKit issue with a sidebar + full-size content window + titlebar accessory setup. The main problem is that an NSTitlebarAccessoryViewController can visually cover the first item in the sidebar when System Settings > Accessibility > Display > Reduce Transparency is enabled. In my app this made the first sidebar/menu item look blacked out/covered by the titlebar/accessory area. While investigating possible workarounds, I also compared NSTitlebarAccessoryViewController with NSSplitViewItemAccessoryViewController and found two related issues that make the split-view accessory hard to use as a replacement. I could not attach the full sample project directly, so I included the two relevant Swift files below. The screenshots were taken from the same minimal AppKit repro with Reduce Transparency enabled. Repro setup The sample project shows: a fixed-width sidebar one content pane using NSTitlebarAccessoryViewController one content pane using NSSplitViewItemAccessoryViewController both accessories use the same custom view both custom views request the same intrinsic height each accessory displays its requested and actual height main.swift AppDelegate.swift Issue 1: titlebar accessory can cover sidebar content With Reduce Transparency enabled, the titlebar/accessory area can visually cover content at the top of the sidebar. This is the original issue I’m trying to solve. Expected: the sidebar content should not be covered by the titlebar accessory/material. Actual: the top sidebar item can appear blacked out/covered. In the first attached screenshot, "First sidebar row" is hidden/covered while "Second row" and the following rows are still visible. Issue 2: split-view accessory does not get the same hard separator As a possible workaround, I tried using NSSplitViewItemAccessoryViewController instead of NSTitlebarAccessoryViewController. Both controllers are configured with: if #available(macOS 26.1, *) { accessory.preferredScrollEdgeEffectStyle = .hard } The titlebar accessory shows the expected hard boundary/separator behavior, but the split-view item accessory does not appear to get the same hard edge treatment. The second attached screenshot shows the workaround comparison between the titlebar accessory and the split-view accessory. Expected: preferredScrollEdgeEffectStyle = .hard should produce a comparable hard separator for the split-view accessory. Actual: the split-view accessory still looks visually different and does not show the same hard boundary. Issue 3: split-view accessory is inset differently The NSSplitViewItemAccessoryViewController also appears to be laid out with spacing/insets around it. In the repro, the accessory custom view has a faint red background. Both accessory views request and receive the same height: requested 36 pt, actual 36.0 pt So the mismatch does not seem to be caused by the accessory view’s own intrinsic height. Instead, the split-view accessory appears to be hosted inside an inset container, with spacing around it, while the titlebar accessory is flush with the titlebar/content edge. Expected: if both accessories host the same view with the same intrinsic height, their effective placement should be comparable, or there should be a documented way to remove/control the split accessory insets. Actual: the split-view accessory is visually inset on multiple sides, making it unsuitable as a drop-in workaround for the titlebar accessory issue. The second attached screenshot also shows this: the split-view accessory has the same requested and actual height as the titlebar accessory, but it is still visually inset and does not align the same way. Question Is this expected behavior on macOS 26, especially with Reduce Transparency enabled? If so, what is the recommended AppKit approach for placing a filter/search accessory below the toolbar/titlebar without covering sidebar content, while still getting a hard separator and predictable layout?
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
1
Boosts
0
Views
228
Activity
1w
Challenges using SwiftUI views inside an NSToolbarItem
I'm trying to use SwiftUI views inside an NSToolbarItem, and I feel like I'm fighting the system. The goal is to create custom toolbar controls. I don't want AppKit or SwiftUI to recognize that there's a SwiftUI view in the toolbar and then try to style it automatically, which is what I think is happening. Consider this hierarchy: - NSToolbar - NSToolbarItem - view -> MyCustomNSView - addSubview(NSHostingView<CustomView>) So CustomView is inside an NSHostingView, which is inside an NSView, which is assigned to the .view property of an NSToolbarItem. For a while, I struggled to get this working at all because SwiftUI's layout metrics appeared to be affected by safe area insets. SwiftUI's ignoresSafeArea() only seemed to move the problem around. For now, I've disabled full-size content view, which I don't really need anyway. However, a SwiftUI Button or Menu still doesn't behave or style the way I would expect when placed inside an NSToolbarItem. They don't seem to honor many of the styling attributes or view modifiers that work elsewhere. Is there a way to tell AppKit to "ignore" the children of my NSToolbarItem and not apply toolbar-specific styling to them? Am I even correct in thinking that AppKit is recognizing a Button or Menu in the toolbar and forcibly applying styling to it? Previously, I tried implementing my "custom toolbar" entirely outside of NSToolbar, but then SwiftUI struggled with placing views under the transparent, non-existent toolbar. I'd appreciate any direction or hints here. It would be really nice to use SwiftUI for the controls I have in mind, but at the moment I can't get close to the result I'm aiming for.
Replies
0
Boosts
0
Views
119
Activity
1w
How do I get content to blur behind a floating input bar, like Mail, Messages and other native apps do?
I have a chat app with a floating composer pill (NSGlassEffectView) pinned to the bottom of my content area. Messages scroll behind it. The pill looks fine but content behind it is completely clear. Fully legible text showing through, no frosting at all. Mail, Messages, Notes all have this frosted look where content behind a floating bar is blurred enough that you can't read it. That's what I'm going for. My scroll view has wantsLayer = true. I tried hasVerticalScroller = true + scrollerStyle = .overlay based on a tip I saw in another thread. No change. Is NSGlassEffectView supposed to blur what's behind it, or is the frosting in Apple's apps coming from the scroll edge effect? If it's the scroll edge effect, is there any way to trigger it for a custom floating view at the bottom of a scroll view? I can't find any AppKit API for this. I also spent time trying this in SwiftUI using .glassEffect() on macOS. Same result, the material renders nearly clear with no way to control the frosting level via any public API. If I'm missing something obvious I'd love to know. I've been stuck on this one for a while. Thanks for any advice! I've attached photos of my input bar (clearly transparent) and Apple Messages, which has a style that I see all over iOS and Mac OS 26.
Replies
0
Boosts
0
Views
214
Activity
2w
NSTextView.shouldDrawInsertionPoint doesn't work with TextKit 2
The following code only ever causes shouldDrawInsertionPoint to be printed (no drawInsertionPoint), but even if that method returns false, the blinking insertion point is still drawn. On the other hand, with TextKit 1 it works as expected. Is there a way to hide the default insertion point in TextKit 2? My app draws its own. I've filed FB13684251. class TextView: NSTextView { override var shouldDrawInsertionPoint: Bool { print("shouldDrawInsertionPoint") return false } override func drawInsertionPoint(in rect: NSRect, color: NSColor, turnedOn flag: Bool) { print("drawInsertionPoint", flag) } } ``
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
11
Boosts
0
Views
635
Activity
2w
AppKit & State Restoration: Windows Auto Closing On App Quit Breaks State Restoration
I probably should know the answer to this but I don't, so I'll ask. When I enable state restoration and have like three windows open, and I quit the app (via Quit menu, not 'Stop In Xcode') the following happens: -NSApplication calls _closeForTermination on all the windows and this causes state restoration to fail to restore these open windows on next app launch. This behavior is not aligned with the behavior of apps like Mail. If I have two "Viewer Windows" open in Mail and I quit the app, when I relaunch the two viewer windows are restored. I can of course track this and write data to restore for these auto closed window myself but shouldn't there be an easy way to opt in to this behavior?
Replies
1
Boosts
0
Views
210
Activity
2w
After binding to NSBrowser indexPaths the browser assumes I'm using NSBrowserCell and calls unimplemented methods on my NSCell subclass
So after binding to NSBrowser selectionIndexPaths: https://developer.apple.com/library/archive/documentation/Cocoa/Reference/CocoaBindingsRef/BindingsText/NSBrowser.html this causes NSBrowser to do some weird stuff that seems completely unrelated to this particular binding. It starts calling NSBrowserCell methods on my cells but my cell is not a NSBrowserCell. My cell is actually a subclass of NSTextFieldCell. But NSBrowser starts sending setIsLeaf: (which I don't implement). In any case if I implement the -setLeaf: that solves that unrecognized selector, but now my cells don't draw titles. Not sure why binding to selectionIndexPaths causes this behavior? The cell stuff seems unrelated to this particular binding. I am of course using the newer but still pretty old item based APIs... do these bindings only support using NSMatrix? I do set the binding after calling -setCellClass: but makes no difference. I also just tried overriding -setSelectionIndexPaths: but NSBrowser does not use the setter.
Replies
2
Boosts
0
Views
239
Activity
2w
Overlay window above all windows, even when moving spaces
Hi! I would like to overlay a macOS application window above all windows, even when moving spaces or moving to a fullscreen app, similar in function to the DropOver app for macOS. What I have tried: Overwriting the default app delegate in SwiftUI and creating the NSWindow myself. Then setting the window.collectionBehavior to [.canJoinAllApplications, .canJoinAllSpaces, .fullScreenAuxiliary] and the window.level to .floating or .statusBar. This works for moving between Spaces, but still does not display above apps in fullscreen mode. I also registered a notification observer for NSWorkspace.activeSpaceDidChangeNotification, where I call window.orderFrontRegardless() to always have my window frontmost. Still not displaying above fullscreen apps. What am I missing to make this work? Best regards
Replies
2
Boosts
0
Views
178
Activity
3w
How do I make an editable NSTextField wrap inside an NSTableView cell?
Hi, I’m pretty new to AppKit and I’m trying to make an NSTextField inside an NSTableView both: Editable Multi-line / wrapping Right now, wrapping works fine until I set: tf.isEditable = true Then the text becomes a single line. How do I make it editable while still wrapping correctly? import AppKit final class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { let tableView = NSTableView() let text = String(repeating: "A", count: 500) override func viewDidLoad() { super.viewDidLoad() view = tableView tableView.addTableColumn(NSTableColumn()) tableView.usesAutomaticRowHeights = true tableView.dataSource = self tableView.delegate = self } func numberOfRows(in tableView: NSTableView) -> Int { 1 } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { let cell = NSTableCellView() let tf = NSTextField(wrappingLabelWithString: text) tf.lineBreakMode = .byCharWrapping if let tableColumn { tf.preferredMaxLayoutWidth = tableColumn.width } tf.isEditable = true // comment this out and wrapping works cell.addSubview(tf) tf.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tf.leadingAnchor.constraint(equalTo: cell.leadingAnchor), tf.trailingAnchor.constraint(equalTo: cell.trailingAnchor), tf.topAnchor.constraint(equalTo: cell.topAnchor), tf.bottomAnchor.constraint(equalTo: cell.bottomAnchor), ]) return cell } }
Replies
4
Boosts
0
Views
300
Activity
3w
SwiftUI + AppKit context menu wedges window-level mouse events when the menu's anchor view is deleted by the menu's own action
I'm on macOS 26.4 (SwiftUI + SwiftData + AppKit bridging). I have a SwiftUI canvas where each child view (a card) carries a per-card AppKit context menu via an NSViewRepresentable overlay (a small NSView subclass that overrides menu(for:) and returns an NSMenu whose items invoke a Swift closure). The closure for the "Delete" item removes the underlying model object. SwiftData mutates → SwiftUI re-emits the canvas → the card containing the menu's anchor NSView unmounts → that anchor NSView is removed from the AppKit view hierarchy. After this happens, the entire window's SwiftUI gestures stop receiving mouse events: pan, zoom, taps on a separate background Color view all go silent. The window's first responder ends up at the NSWindow itself. The wedge persists across switching to a sibling SwiftUI view in the same window (different SwiftData root), so the bad state is at the window/event-routing level, not in any one SwiftUI subtree. The wedge is reliably cleared by another right-click that successfully shows + dismisses any menu — strongly suggesting AppKit's menu/event-tracking cleanup is left in a half-finished state because the anchor view went away during the cleanup window. I've already verified: Switching from explicit NSMenu.popUpContextMenu(_:with:for:) to overriding menu(for:) does not change the behavior. Deferring the model deletion via DispatchQueue.main.async, asyncAfter (30 ms), or RunLoop.main.perform(inModes: [.default]) either doesn't help or only avoids the wedge if the delay is long enough to be perceptible (seconds), implying the cleanup window is event-driven, not time-driven. Triggering the same deletion from a SwiftUI Button (no AppKit menu involved) never wedges. My current understanding is that the standard AppKit pattern (e.g., NSTableView, NSOutlineView) attaches the context menu to a stable parent view, never to the per-row view itself, precisely so the menu's anchor outlives any single row's deletion. Restructuring my code so a single canvas-level AppKitContextMenuRegion returns the appropriate menu via hit-testing in menu(for:) should avoid the issue, but I'd like to confirm: Is the assumption that an NSMenu's anchor view must outlive the menu's tracking-end cleanup documented anywhere, or is it implicit? Is there a supported way to safely use a per-row anchor view that gets deleted by the menu's own action, or is the canvas-level / parent-level menu attachment the only correct pattern? 3. Are there any post-tracking notifications or APIs that guarantee AppKit's cleanup is complete before the anchor view is allowed to be torn down (so a per-row anchor could be made safe with the right ordering)? Thanks!
Replies
0
Boosts
0
Views
355
Activity
3w
NSCollectionView's 'selection box' freezes if you right-click during dragging
So in NSCollectionView I left click the background and start dragging to make the 'selection box' (is that what we call it?) I have a mouse with separate left and right click buttons (i.e., not an Apple Magic Mouse). Now if I accidentally hit the right click while I'm still dragging the selection box..... the right click context menu shows up in the middle of mouse dragging and the selection box freezes on screen. Besides the visual disruption this sometimes results in weird behavior. Sometimes mouse clicks stop responding for awhile in the window and I gotta click around a bunch of times until I guess the run loop "unclogs." I'm able to reproduce in Finder Icon view so it isn't just me. Steps to Reproduce: A mouse with separate buttons for left and right click. Open Finder window in icon view. Left click the background and start dragging to make the gray selection box. While dragging the mouse as you are selecting click right-click in the middle of the drag. The selection box freezes on screen. Expected Behavior: -Right click event and left mouse drag event normally shouldn't overlap. If left mouse is being dragged the right click event should be blocked. Let me know if this is Feedback worthy.
Replies
5
Boosts
0
Views
284
Activity
May ’26
.icon files and "imageNamed:"
Composer icons can be loaded with NSImage's imageNamed: but I haven't figured out how to make it load any variation other than the light style. Is this even possible? Thank you!
Replies
1
Boosts
0
Views
198
Activity
May ’26
Remove MacOS Tahoe Sidebar + Inspector Chrome
Is it possible to remove the ugly sidebar and inspector chrome with AppKit? I don't care if it's a hack or a swizzle or something, but I need to get rid of this. I want to convert this: Into this (photoshopped): Thanks for your help!
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
0
Boosts
1
Views
318
Activity
May ’26
How can I reliably get the final restored window size on macOS when onAppear / viewDidAppear fires too early?
I’m running into a macOS window restoration behavior issue where viewDidAppear (AppKit) or onAppear (SwiftUI) fires before the window’s final restored size is applied. AppKit example class MyViewController: NSViewController { override func viewDidLayout() { print("viewDidLayout: \(view.bounds.size)") } override func viewDidAppear() { print("viewDidAppear: \(view.bounds.size)") } } Logs on launch: viewDidAppear: (480.0, 270.0) viewDidLayout: (480.0, 270.0) viewDidLayout: (556.0, 476.0) viewDidLayout: (556.0, 476.0) The correct restored size is (556.0, 476.0), but viewDidAppear initially reports the old default size (480.0, 270.0). SwiftUI equivalent struct MyView: View { var body: some View { GeometryReader { geo in VStack {} .onAppear { print("onAppear: \(geo.size)") } .onChange(of: geo.size) { print("onChange: \(geo.size)") } } } } Logs on launch: onAppear: (900.0, 450.0) onChange: (680.0, 658.0) Problem I need to run some setup code: Only once After the view/window has its correct restored size Without rerunning on every layout or geometry change Question What is the proper macOS-native way to perform one-time startup logic only after the final restored window size is available? Is there a recommended lifecycle hook or pattern for this? Also, is it expected behavior that onAppear / viewDidAppear reports the pre-restoration size, or is it a bug?
Replies
3
Boosts
0
Views
362
Activity
May ’26
ScrollView/ClipView weirdness.
I have been playing around with AppKit programming and I have a sample document based app with a scroll view and rulers. When The scrollbars are not overlay style (which is usually true for me because I have "show scroll bars always" set in preferences) and the rulers are on The clip view seems to extend throughout the scroll view and the document can be seen through the scroll bars. However if I turn the rulers off, then the clip view seems to not include the scroll bars, and so the document is not visible through the scroll bars, having been clipped to the rectangle that lies inside the scroll bars. Additionally in this case, the small area in the lower right hand corner of the screen between the two scroll bars is white, even though all of my views have a light gray background. If the scroll bar style is overlay, then everything seems to work as expected: the clip view always includes the scroll bars. Is this a bug related to legacy style scrollbars or (more likely) have I just screwed something up? I should add that the window and the entire view hierarchy have been built programmatically. It is not in the xib.
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
1
Boosts
0
Views
422
Activity
May ’26
macOS main.swift and Main actor-isolated conformance cannot be used in nonisolated context
For a simple, resourceless cocoa apps I used to manually setup the application lifecycle (mimicking what's documented here: https://developer.apple.com/documentation/appkit/nsapplication), so my main.swift would look like: import Cocoa let delegate = SomeDelegate() _ = NSApplication.shared NSApp.delegate = delegate NSApp.run() This triggers a warning in Xcode 26.2: "Main actor-isolated conformance of SomeDelegate cannot be used in nonisolated context; this is an error in Swift 6 language mode". so what is the recommended way to refactor above so that it is Swift 6 compliant?
Replies
1
Boosts
0
Views
1.1k
Activity
Apr ’26
-applicationDockMenu: method on NSApplicationDelegate doesn't work when attached to debugger
When I add a simple menu to the dock via the NSApplicationDelegate method -applicationDockMenu: and run the app from Xcode it doesn't work. -(NSMenu*)applicationDockMenu:(NSApplication*)sender { NSMenu *dockMenu = [self buildDockMenu]; if (dockMenu != nil) { NSLog(@"Returning dock menu."); return dockMenu; } else { NSLog(@"Not ready to build dock menu"); return nil; } } When I run the app, my main app window shows up but nothing logs out in -applicationDockMenu: until I click outside my app's window (so if I click the desktop background, or a Finder window, or whatever). Then after I click outside my app's main window this logs out: Returning dock menu. The "Not ready to build dock menu" message does not log out. But...when I right click on the dock icon, the menu doesn't show up. But if I stop the app from Xcode and just run it not attached to the debugger, the dock menu does show up. But this makes the debugging/testing situation not ideal.
Replies
4
Boosts
0
Views
426
Activity
Apr ’26
NSOutlineView / NSTableView's Setting lineScroll to a somewhat absurd value of 304 in -tile
So I'm working on adding another component to my app that uses NSOutlineView, as we do in AppKit. There will probably always be less than 25 rows here. One row is much larger than the others. Not sure if any of this matters. What I know is I noticed scrolling it is very jank. It's going way too fast. So I took a peek and see lineScroll is getting is 304 in Interface Builder. Not sure how that happened. I changed it to like 24. Then Interface Builder automatically changes it back to 304. So in -viewDidLoad I just set it: NSScrollView *scrollView = self.outlineView.enclosingScrollView; scrollView.verticalLineScroll = 24.0; scrollView.lineScroll = 24.0; But scrolling still is busted. So I subclass NSScrollView and override the setters. For some reason, NSTableView's -tile method is deciding to change the lineScroll to 304, all on its own. So every time tile is called. line scrolls get reset to 304.
Replies
1
Boosts
0
Views
369
Activity
Apr ’26
AppKit - Legal to Change a View's Frame in -viewDidLayout?
I have (had) a view controller that does a bit of manual layout in a -viewDidLayout override. This was pretty easy to manage - however since introducing NSGlassEffectView into the view hierarchy I sometimes am getting hit with "Unable to simultaneously satisfy constraints" and Appkit would break a constraint to 'recover.' It appears translatesAutoresizingMaskIntoConstraints is creating some really weird fixed width and height constraints. Here I wasn't doing any autolayout - just add the glass view and set its frame in -viewDidLayout. At runtime since I do manual layout in -viewDidLayout the frames are fixed and there is no real "error" in my app in practice though I wanted to get rid of the constraint breaking warning being logged because I know Autolayout can be aggressive about 'correctness' who knows if they decide to throw and not catch in the future. In my perfect world I would probably just prefer a view.doesManualLayout = YES here - the subviews are big containers no labels so localization is not an issue for me. Rather than playing with autoresizing masks to get better translated constraints I decided to set translatesAutoresizingMaskIntoConstraints to NO and make the constraints myself. Now I get hit with the following exception: "The window has been marked as needing another Layout Window pass, but it has already had more Layout Window passes than there are views in the window" So this happens because the view which now has constraints -- I adjusted the frame of it one point in -viewDidLayout. My question is - is not legal to make changes in -viewDidLayout - which seems like the AppKit version of -viewDidLayoutSubviews. In UIKit I always thought it was fine to make changes in -viewDidLayoutSubviews to frames - even if constraints were used - this is a place where you could override things in complex layouts that cannot be easily described in constraints. But in AppKit if you touch certain frames in -viewDidLayout it can now cause this exception (also related: https://developer.apple.com/forums/thread/806471) I will change the constant of one of the constraints to account for the 1 point adjustment but my question still stands - is it not legal to touch frames in -viewDidLayout when autolayout constraints are used on that subview? It is (or at least was if I remember correctly) permitted to change the layout in -viewDidLayoutSubviews in UIKit but AppKit seems to be more aggressive in its checking for layout correctness). What about calling -sizeToFit on a control in viewDidLayout or some method that has side effect of invalidating layout in a non obvious way, is doing things like this now 'dangerous?' Shouldn't AppKit just block the layout from being invalidated from within -viewDidLayout - and leave whatever the layout is as is when viewDidLayout returns (thus making -viewDidLayout a useful place to override layout in the rare cases where you need a sledgehammer?)
Replies
4
Boosts
0
Views
763
Activity
Apr ’26