Skip to content

Instantly share code, notes, and snippets.

@kamanov
Last active September 14, 2025 21:04
Show Gist options
  • Select an option

  • Save kamanov/3dff69fabb6deacf7fb749d47e3f5088 to your computer and use it in GitHub Desktop.

Select an option

Save kamanov/3dff69fabb6deacf7fb749d47e3f5088 to your computer and use it in GitHub Desktop.
swiftui zoom transition options
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