Skip to content

Fix incorrect sort order of NavigationStack#169

Draft
DavidBrunow wants to merge 4 commits intocashapp:mainfrom
DavidBrunow:bugfix/navigationStackSortOrder
Draft

Fix incorrect sort order of NavigationStack#169
DavidBrunow wants to merge 4 commits intocashapp:mainfrom
DavidBrunow:bugfix/navigationStackSortOrder

Conversation

@DavidBrunow
Copy link
Contributor

Fixes #168.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm on an Apple Silicon Mac so these snapshots might not be generated as needed.

@@ -0,0 +1,30 @@
//
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know y'all just got rid of this, but I brought it back because the navigation buttons were not being rendered when using only the SwiftUI views.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, they weren't being rendered at all? The only thing that should be different between these is how the view is sized (setting the frame vs. bounds). Might affect the safe area insets, but everything should still be rendered.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm sorry, I misspoke. The button is getting rendered but it is not included as an accessibility element

testNavigationStack 393x852-16-4-3x

Changing this code from bounds to frame resolves the issue: https://github.com/cashapp/AccessibilitySnapshot/blob/master/Sources/AccessibilitySnapshot/SnapshotTesting/SnapshotTesting%2BSwiftUI.swift#L68

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't love this fix but from my very small set of tests it works. Next week I'm going to check against our tests at work to see if anything breaks with this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've checked our tests at work and see no regression from this change.

assertSnapshot(matching: viewController, as: .imageWithSmartInvert, named: nameForDevice())
}

@available(iOS 16.0, *)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I remember correctly this doesn't do quite enough to make the tests pass and I'll need to add an XCTSkip.

@DavidBrunow DavidBrunow marked this pull request as draft November 5, 2023 13:13
@DavidBrunow
Copy link
Contributor Author

@NickEntin any feedback on this pull request? I think it is ready to come out of draft status but I want to make sure y'all are good with it.

Comment on lines +605 to +611
let explicitOrderingExceptionList = [
"UILayoutContainerView",
"UpdateCoalescingCollectionView",
]
Copy link
Collaborator

Choose a reason for hiding this comment

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

While this fixes the specific bug we have a repro case for, I suspect it's hiding a larger issue around how we're matching VoiceOver's treatment of accessibility containers. If we recreate the same accessibility hierarchy of a UILayoutContainerView or UpdateCoalescingCollectionView do we get the same incorrect results? Looks like they might be using containers of containers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Digging into this to try to understand it better.

Copy link
Contributor Author

@DavidBrunow DavidBrunow Dec 29, 2023

Choose a reason for hiding this comment

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

Update with what I've found so far:

Both the NavigationView and NavigationStack have a UILayoutContainerView in their view hierarchy -- in general both view hierarchies look very similar. The key difference between the two is that the UILayoutContainerView in the NavigationView has shouldGroupAccessibilityChildren set to true while in the NavigationStack it is set to false.

This is key to the problem because the shouldGroupAccessiblityChildren property is what is used to determine whether a group of accessibility elements has explicitlyOrdered set to false: https://github.com/cashapp/AccessibilitySnapshot/blob/master/Sources/AccessibilitySnapshot/Core/Swift/Classes/AccessibilityHierarchyParser.swift#L631

To me this points to what you mentioned: a larger issue around how the library is matching VoiceOver's treatment of accessibility containers. In specific I think we need improvements to how explicitlyOrdered is determined, or maybe how it is used to create the sorted elements, but I don't have suggestions at this time.

let explicitlyOrdered = accessibilityElements.contains {
explicitOrderingExceptionList.contains("\(type(of: $0))") == false
}
let shouldBeExplicitlyOrdered = accessibilityHierarchyOfElements.contains { node in
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is another approach to determining whether a group should be explicitly ordered. I need to think it through a bit more but I think this matches how VoiceOver works since the ordering is determined by the order of the accessibilityElements array.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@NickEntin could I get your thoughts on this approach?

@DavidBrunow DavidBrunow force-pushed the bugfix/navigationStackSortOrder branch from 010671b to 4321111 Compare February 27, 2024 13:50
@yonaskolb
Copy link

Would love to see this land at some point. Seems it may fix #129 as well?

@yonaskolb
Copy link

Just tested and this does indeed fix #129

@DavidBrunow
Copy link
Contributor Author

Just tested and this does indeed fix #129

I need to pick this back up again, will try to do so soon.

@yonaskolb yonaskolb mentioned this pull request Jun 14, 2025
@yonaskolb
Copy link

Any updates on this one, especially after #244 was merged?

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.

Incorrect sort order when using NavigationStack

3 participants

Comments