pointfreeco / swift-composable-architecture

A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind.
https://www.pointfree.co/collections/composable-architecture
MIT License
12.22k stars 1.42k forks source link

dismiss is not working after multiple views were closed by UIKit #2398

Closed safarafa closed 1 year ago

safarafa commented 1 year ago

Description

Child view is shown using @PresentationState in parent view, and both of them are shown in hybrid application, using UIHostingController shown as modal in new UINavigationController, and this whole modal view is dismissed (by UIKit method). When we'll show child view again, TCA's dismiss method is not working - actions are sent, the state is set to nil, but the corresponding view is still visible. It might be bug, because apparently the state is not nil after cancelling process.

Sample app

Checklist

Expected behavior

Using .dismiss() should remove view and set state to nil.

Actual behavior

Using .dismiss() is not removing view and the state is not nil.

Steps to reproduce

  1. Download and run sample app, on device or simulator.
  2. Tap "Dismiss test"
  3. Tap "Tap to see first level child"
  4. Tap "Dismiss using UIKit"
  5. Tap "Dismiss test"
  6. Tap "Dismiss this Child" Reproduction rate: 3/5 (sometime dismiss works).

The Composable Architecture version information

1.1.0 and below

Destination operating system

iOS 14

Xcode version information

14.3.1

Swift Compiler version information

Apple Swift version 5.8.1
mbrandonw commented 1 year ago

Hi @safarafa, this is the expected behavior of \.dismiss. All it does is find the closest optional state that is driving some kind of navigation and nils it out in order to undo the navigation. So, in your case it finds @PresentationState var child and nils out the child state, causing the screen to be popped off the stack.

It's worth noting that this is exactly how @Environment(\.dismiss) works in vanilla SwiftUI.

Since this is not an issue with the library I will convert this to a discussion. Feel free to continue discussing over there if you have more questions.