Last active
September 14, 2025 21:04
-
-
Save kamanov/3dff69fabb6deacf7fb749d47e3f5088 to your computer and use it in GitHub Desktop.
swiftui zoom transition options
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| import SwiftUI | |
| public typealias ZoomInteractiveDismissHandler = (UIViewController.Transition.ZoomOptions.InteractionContext) -> Bool | |
| public extension View { | |
| func zoomInteractiveDismissShouldBegin(_ handler: @escaping ZoomInteractiveDismissHandler) -> some View { | |
| modifier(ZoomTransitionModifier(interactiveDismissShouldBegin: handler)) | |
| } | |
| } | |
| private struct ZoomTransitionModifier: ViewModifier { | |
| var interactiveDismissShouldBegin: ((UIViewController.Transition.ZoomOptions.InteractionContext) -> Bool)? | |
| func body(content: Self.Content) -> some View { | |
| content | |
| .background { | |
| ZoomTransitionAdapter( | |
| interactiveDismissShouldBegin: interactiveDismissShouldBegin | |
| ) | |
| } | |
| } | |
| } | |
| private struct ZoomTransitionAdapter: UIViewControllerRepresentable { | |
| var interactiveDismissShouldBegin: ZoomInteractiveDismissHandler? | |
| func makeUIViewController(context: Self.Context) -> ZoomTransitionAdapterController { | |
| let vc = ZoomTransitionAdapterController() | |
| vc.view.backgroundColor = .clear | |
| vc.view.isUserInteractionEnabled = false | |
| vc.interactiveDismissShouldBegin = interactiveDismissShouldBegin | |
| return vc | |
| } | |
| func updateUIViewController(_ uiViewController: ZoomTransitionAdapterController, | |
| context: Self.Context) { | |
| uiViewController.interactiveDismissShouldBegin = interactiveDismissShouldBegin | |
| } | |
| } | |
| private final class ZoomTransitionAdapterController: UIViewController { | |
| var interactiveDismissShouldBegin: ZoomInteractiveDismissHandler? { | |
| didSet { | |
| zoomTransitionOptions?.interactiveDismissShouldBegin = interactiveDismissShouldBegin | |
| } | |
| } | |
| private var zoomTransitionOptions: UIViewController.Transition.ZoomOptions? { | |
| parent?.preferredTransition?.value(forKey: "options") as? UIViewController.Transition.ZoomOptions | |
| } | |
| override func viewWillAppear(_ animated: Bool) { | |
| super.viewWillAppear(animated) | |
| zoomTransitionOptions?.interactiveDismissShouldBegin = interactiveDismissShouldBegin | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment