Skip to content

Fix split views on Catalyst#229

Draft
bbrk24 wants to merge 1 commit intomoreSwift:mainfrom
bbrk24:catalyst-splitview
Draft

Fix split views on Catalyst#229
bbrk24 wants to merge 1 commit intomoreSwift:mainfrom
bbrk24:catalyst-splitview

Conversation

@bbrk24
Copy link
Contributor

@bbrk24 bbrk24 commented Oct 20, 2025

Draft until I can test that I didn't break it on iPad

@bbrk24 bbrk24 marked this pull request as ready for review October 22, 2025 23:26
Copy link
Collaborator

@stackotter stackotter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this. When testing out your changes locally I managed to make the app freeze in a resize handling update loop indefinitely by resizing the app a bunch and getting unlucky. I reproduced that behaviour a few times and couldn't on main so I think there may be some sort of feedback loop in your current layoutSubviews-based approach. I'm not exactly sure what the solution is to that.

I also noticed that the splits get allocated rather strange sizes (especially when you switch to the three column example), but I get the same behaviour on main so that doesn't necessarily need to be fixed in this PR.

@stackotter
Copy link
Collaborator

It seems like split views under Mac Catalyst still have issues with sizing the panes after certain types of view updates. That said, I'm happy to merge in this PR as is because it does fix resize handling under Mac Catalyst and doesn't make anything worse. If I did so I'd just rename it to make the purpose of the PR more clear.

Let me know if you'd like to tackle the initial sizing issues in this PR or if I should merge and open an issue for that to be tackled in the future.

Here are the pre-existing sizing issues I'm talking about;

Open the app (odd sizing, but not invalid):
Screenshot 2025-11-28 at 2 48 47 pm

Switch to 3 columns (first column overflows):
Screenshot 2025-11-28 at 2 48 58 pm

Select science (first and second columns overflow):
Screenshot 2025-11-28 at 2 49 09 pm

Switch to 2 columns (both columns overflow/overlap):
Screenshot 2025-11-28 at 2 49 17 pm

Prevent resizeHandler() from being called twice in one pass
@bbrk24 bbrk24 force-pushed the catalyst-splitview branch from bcee7e0 to 28efb86 Compare January 11, 2026 23:35
@bbrk24
Copy link
Contributor Author

bbrk24 commented Jan 11, 2026

Open the app (odd sizing, but not invalid):

I can no longer reproduce this after rebase:
Screenshot 2026-01-11 at 6 36 16 PM

However, the button is pushed off the bottom of the screen, and I'm not sure whether that's a bug with the new layout system. If I fullscreen the window, the button becomes visible, but clicking it still doesn't do anything.

@stackotter
Copy link
Collaborator

Interesting, I’ll try reproducing it myself as well (once I’m at my laptop).

@stackotter
Copy link
Collaborator

stackotter commented Jan 12, 2026

Huh yeah this is really weird. It looks ok now but I can't click the sidebar buttons or the bottom button. And when I resize the split to the right, the trailing split's content moves to the left and overlaps the sidebar 😅 I don't think that that was introduced by your PR though

@stackotter
Copy link
Collaborator

Feels like maybe a missing translatesAutoresizingMaskIntoConstraints somewhere given that the trailing content isn't centered? And maybe an inverted coordinate?

The button going off the bottom of the screen leads me to believe that UIKitBackend is including the title bar when giving us the size of the window.

@bbrk24
Copy link
Contributor Author

bbrk24 commented Feb 8, 2026

I have rebased this locally, but I'm hesitant to push up the changes because SplitExample on Catalyst now crashes with this error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSLayoutConstraint constant is not finite!  That's illegal.  constant:inf firstAnchor:<NSLayoutDimension:0x6000000da640 "UINSSceneView:0x158e16f00.width"> secondAnchor:(null)'
*** First throw call stack:
(
	0   CoreFoundation                      0x0000000196163a30 __exceptionPreprocess + 176
	1   libobjc.A.dylib                     0x0000000195c26b90 objc_exception_throw + 88
	2   Foundation                          0x0000000197773a78 -[NSCalendarDate initWithCoder:] + 0
	3   CoreAutoLayout                      0x000000019f89fa3c -[NSLayoutConstraint _setSymbolicConstant:constant:symbolicConstantMultiplier:] + 568
	4   CoreAutoLayout                      0x000000019f89fb38 -[NSLayoutConstraint setConstant:] + 84
	5   UIKitMacHelper                      0x00000001b1638b78 -[UINSSceneContainerView updateConstraints] + 2976
	6   UIKitMacHelper                      0x00000001b1626d98 -[UINSSceneViewController updateViewConstraints] + 64
	7   AppKit                              0x000000019a0945ac -[NSView _updateConstraintsForSubtreeIfNeededCollectingViewsWithInvalidBaselines:] + 608
	8   AppKit                              0x000000019ab32f8c __45-[NSView updateConstraintsForSubtreeIfNeeded]_block_invoke_2 + 52
	9   AppKit                              0x000000019a0941b0 __45-[NSView updateConstraintsForSubtreeIfNeeded]_block_invoke + 224
	10  AppKit                              0x000000019a053000 NSPerformVisuallyAtomicChange + 108
	11  AppKit                              0x000000019a0940c4 -[NSView updateConstraintsForSubtreeIfNeeded] + 96
	12  AppKit                              0x000000019ab33a34 __70-[NSView _updateConstraintsForLayoutCheckingDirtyBits:creatingEngine:]_block_invoke + 256
	13  AppKit                              0x000000019a053000 NSPerformVisuallyAtomicChange + 108
	14  AppKit                              0x000000019a093ff4 -[NSView _updateConstraintsForLayoutCheckingDirtyBits:creatingEngine:] + 132
	15  AppKit                              0x000000019ab33c24 __56-[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:]_block_invoke + 264
	16  AppKit                              0x000000019a053000 NSPerformVisuallyAtomicChange + 108
	17  AppKit                              0x000000019a057444 -[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:] + 100
	18  AppKit                              0x000000019a053000 NSPerformVisuallyAtomicChange + 108
	19  AppKit                              0x000000019a0573d4 -[NSView layoutSubtreeIfNeeded] + 96
	20  AppKit                              0x000000019ab5a8dc +[NSWindow _windowWithContentViewController:styleMask:] + 48
	21  UIKitMacHelper                      0x00000001b1625d88 -[UINSSceneWindowController loadWindow] + 188
	22  AppKit                              0x000000019a173b18 -[NSWindowController window] + 80
	23  UIKitMacHelper                      0x00000001b163c4a8 -[UINSApplicationDelegate _configureWindowControllerCreatingIfNeededForScene:transitionContext:] + 520
	24  UIKitMacHelper                      0x00000001b163b56c -[UINSApplicationDelegate didCreateUIScene:transitionContext:] + 412
	25  UIKitCore                           0x00000001ca7b879c __75-[UIApplication workspace:didCreateScene:withTransitionContext:completion:]_block_invoke_3 + 48
	26  libdispatch.dylib                   0x0000000195e4fb2c _dispatch_call_block_and_release + 32
	27  libdispatch.dylib                   0x0000000195e6985c _dispatch_client_callout + 16
	28  libdispatch.dylib                   0x0000000195e86b80 _dispatch_main_queue_drain.cold.5 + 812
	29  libdispatch.dylib                   0x0000000195e5edb0 _dispatch_main_queue_drain + 180
	30  libdispatch.dylib                   0x0000000195e5ecec _dispatch_main_queue_callback_4CF + 44
	31  CoreFoundation                      0x0000000196130b30 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
	32  CoreFoundation                      0x00000001960f182c __CFRunLoopRun + 1980
	33  CoreFoundation                      0x00000001960f09e8 CFRunLoopRunSpecific + 572
	34  HIToolbox                           0x00000001a1b9127c RunCurrentEventLoopInMode + 324
	35  HIToolbox                           0x00000001a1b944e8 ReceiveNextEventCommon + 676
	36  HIToolbox                           0x00000001a1d1f484 _BlockUntilNextEventMatchingListInModeWithFilter + 76
	37  AppKit                              0x000000019a011a34 _DPSNextEvent + 684
	38  AppKit                              0x000000019a9b0940 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 688
	39  AppKit                              0x000000019a004be4 -[NSApplication run] + 480
	40  AppKit                              0x0000000199fdb2dc NSApplicationMain + 880
	41  AppKit                              0x000000019a227c84 +[NSWindow _savedFrameFromString:] + 0
	42  UIKitMacHelper                      0x00000001b1623164 UINSApplicationMain + 976
	43  UIKitCore                           0x00000001c97eac9c UIApplicationMain + 148
	44  SplitExample                        0x0000000104dcf230 $s12UIKitBackendAAC11runMainLoopyyyyScMYccF + 460
	45  SplitExample                        0x0000000104dd0d84 $s12UIKitBackendAAC12SwiftCrossUI03AppB0AacDP11runMainLoopyyyyScMYccFTW + 20
	46  SplitExample                        0x0000000104bdc698 $s12SwiftCrossUI4_AppC3runyyF + 252
	47  SplitExample                        0x0000000104914b4c $s12SwiftCrossUI3AppPAAE4mainyyFZ + 528
	48  SplitExample                        0x0000000104910ed4 $s12SplitExample0A3AppV5$mainyyFZ + 40
	49  SplitExample                        0x000000010491100c main + 12
	50  dyld                                0x0000000195c66b98 start + 6076
)
libc++abi: terminating due to uncaught exception of type NSException
error: Failed to run executable

@stackotter
Copy link
Collaborator

It sounds like you might have to move some code from computeLayout to commit? Hard to tell without seeing the changes, but it sounds like an intermediate 'maximum size' proposal is being used to update a constraint.

@stackotter stackotter marked this pull request as draft February 23, 2026 00:47
@stackotter
Copy link
Collaborator

I've converted this to a draft for now so that it doesn't keep showing up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants