nathantannar4 / Transmission

Bridges UIKit presentation APIs to a SwiftUI API so you can use presentation controllers, interactive transitions and more.
BSD 2-Clause "Simplified" License
378 stars 13 forks source link

Expose a public init for `PresentationCoordinator` #10

Closed vpontis closed 10 months ago

vpontis commented 10 months ago

For some context, I'm exploring using native SwiftUI sheets for some of our sheets and want to continue using DismissPresentationLink which relies on PresentationCoordinator.

Here is my sheet code:

struct LumaSheetModifier<Destination: View>: ViewModifier {
    var detents: Set<PresentationDetent> = .init([.large])
    var isPresented: Binding<Bool>
    var preferredCornerRadius: CGFloat? = UIScreen.preferredDisplayCornerRadius
    @ViewBuilder var destination: Destination

    @State var isInteractive = LumaSheetInteractiveDismissalDisabled.defaultValue

    func body(content: Content) -> some View {
        content
            .sheet(isPresented: isPresented) {
                destination
                    .modifier(SheetCornerRadiusModifier(cornerRadius: preferredCornerRadius ?? UIScreen.preferredDisplayCornerRadius))
                    .presentationDragIndicator(.hidden)
                    .interactiveDismissDisabled(!isInteractive)
                    .presentationDetents(detents)
                    .modifier(LumaSheetDestinationModifier(isInteractive: isInteractive))
                    .onPreferenceChange(LumaSheetInteractiveDismissalDisabled.self) { newValue in
                        isInteractive = !newValue
                    }
                    /// The `DismissPresentationLink` uses the `presentationCoordinator` so we need to make sure
                    /// that it's in the environment properly.
                    .environment(
                        \.presentationCoordinator,
                         PresentationCoordinator(
                            isPresented: isPresented.wrappedValue,
                            sourceView: nil,
                            dismissBlock: {
                                isPresented.wrappedValue = false
                            }
                        )
                    )
            }
    }
}
vpontis commented 10 months ago

@nathantannar4 can I request your review on this? 😄

nathantannar4 commented 10 months ago

Is this because you're using a mix of native and non-native sheets? DismissPresentationLink should work out of the box with the .sheet modifier since the presentation coordinator used will fallback to SwiftUI's .dismiss action, which should dismiss the native sheet.

If you're using a mix of native and non-native sheets then I can see how the wrong sheet may be dismissed.

It was an intentional choice to make the init of PresentationCoordinator private to enforce consistency.

vpontis commented 10 months ago

Gotcha, we reverted to not mixing Transmission + native sheets so I'll close this!