Unwanted presentation behavior #3723
Replies: 1 comment 3 replies
-
Hi @chaudharyvikram, this project is using a mixture of old an new tools that are not compatible with each other. On the one hand you are using There are also purple runtime warnings explaining exactly what is wrong:
In particular, this second bullet point is your situation. You are using old navigation APIs. I have modernized your demo and now it works just fine: Since this isn't an issue with the library I am going to convert it to a discussion. Please feel free to continue the conversation over there! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Description
I’ve implemented TCA in a large-scale project with over 100 screens to navigate between. For navigation, I followed the official documentation. However, when I added more than 35 cases to the Path enum (specifically in the home screen’s reducer), the app started crashing at runtime when opening the Home tab — but only on real devices, not in the simulator.
To confirm the issue, I created a demo with more than 35 screens, and it worked fine. But even when using a random set of 35+ cases in the main project, the crash persisted on device. After some investigation, I tried replacing the enum with a struct for the path. That resolved the crash, but introduced a new issue — screens started presenting and dismissing in a loop until the app was terminated.
This behavior seems to stem from delegation actions triggered from the presented screens. These actions send messages back to the reducer that originally pushed the screen, which then refreshes the entire navigation path. To avoid this stack refresh, I tried applying .id to the view, which did prevent the refresh — but at the cost of breaking the default present/dismiss animations, and the navigation stack still refreshes 2–3 times in some cases.
I’ve attached both the code and a video that shows the behavior.
Could you please review and let me know if I’ve implemented something incorrectly or misunderstood part of the architecture?
https://share.icloud.com/photos/057FgD4tr_P5LxxLgR1acS_LA
Checklist
main
branch of this package.Expected behavior
Presenting and dismissing screens should animate correctly and behave predictably.
• Sending actions from a presented screen back to its presenter should not reset or refresh the entire navigation path.
• Applying .id() should prevent unnecessary reinitialization or path refreshes without affecting transition animations.
Actual behavior
The app crashes on real devices when the Path enum contains more than 35 cases, particularly when opening the Home tab.
• The issue does not reproduce on the simulator or in isolated demo projects, even with the same number of cases.
• Switching to a struct for navigation path avoids the crash, but causes screens to get stuck in a presentation/dismissal loop.
• This loop is triggered when delegation actions are sent from a presented screen back to the presenting reducer, causing the entire path to refresh.
• Adding .id() to preserve view identity prevents the navigation reset but disables present/dismiss animations and does not fully prevent 2–3 redundant refreshes of the navigation stack.
https://share.icloud.com/photos/057FgD4tr_P5LxxLgR1acS_LA
Reproducing project
TCANavigationStructure 3.zip
The Composable Architecture version information
1.20.2
Destination operating system
iOS 18.5
Xcode version information
Xcode 16.4
Swift Compiler version information
Beta Was this translation helpful? Give feedback.
All reactions