Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save edudnyk/ca6ce0064d4b3f4842524bc0a0ca15fa to your computer and use it in GitHub Desktop.
Save edudnyk/ca6ce0064d4b3f4842524bc0a0ca15fa to your computer and use it in GitHub Desktop.
Initial sandwich solution implementation in SheeKit
struct SheetPresenterControllerRepresentable<Item>: UIViewControllerRepresentable where Item : Identifiable {
@Binding var item: Item?
@Environment(\.shee_isInteractiveDismissDisabled) private var isInteractiveDismissDisabled
let onDismiss: (() -> Void)?
let sheetHostProvider: (AdaptiveDelegate<Item>, UIViewController, Item, DismissAction) -> SheetHostingController<Item>
let sheetHostUpdater: (AdaptiveDelegate<Item>, UIViewController, Bool, DismissAction) -> Void
func makeCoordinator() -> AdaptiveDelegate<Item> { .init() }
func makeUIViewController(context: Context) -> SheetPresenterController { .init() }
func updateUIViewController(_ presenter: SheetPresenterController, context: Context) {
let coordinator = context.coordinator
let dismissAction = dismissAction(coordinator)
coordinator.dismissedByUserCallback = dismissAction
coordinator.isInteractiveDismissDisabled = isInteractiveDismissDisabled
let isCurrentItemSheet = updateSheet(presenter, context: context)
if let sheetHost = coordinator.sheetHost,
sheetHost.itemId != nil,
let presentingViewController = sheetHost.presentingViewController,
!isCurrentItemSheet {
sheetHost.itemId = nil
presentingViewController.dismiss(animated: true)
onDismiss?()
}
if let item = item,
let coordinator = coordinator,
!isCurrentItemSheet {
let sheetHost = sheetHostProvider(coordinator, presenter, item, dismissAction)
sheetHost.onDismiss = onDismiss
sheetHost.presentationController?.delegate = coordinator
presenter.present(sheetHost, animated: true)
}
}
}
func updateSheet(_ presenter: SheetPresenterController, context: Context) -> Bool {
guard let sheetHost = context.coordinator.sheetHost,
sheetHost.presentingViewController != nil else { return false }
let isCurrentItemSheet = item != nil && sheetHost.itemId == item?.id
if isCurrentItemSheet, let item = item {
sheetHost.item = item
sheetHost.onDismiss = onDismiss
}
sheetHostUpdater(context.coordinator, presenter, isCurrentItemSheet, dismissAction(context.coordinator))
return isCurrentItemSheet
}
static func dismantleUIViewController(_ presenter: SheetPresenterController, coordinator: AdaptiveDelegate<Item>) {
if let sheetHost = coordinator.sheetHost,
let presentingViewController = sheetHost.presentingViewController,
sheetHost.itemId != nil {
sheetHost.itemId = nil
presentingViewController.dismiss(animated: true)
sheetHost.onDismiss?()
}
coordinator.sheetHost = nil
}
func dismissAction(_ coordinator: AdaptiveDelegate<Item>) -> DismissAction {
let currentItemId = item?.id
return .init { [weak coordinator] in
guard let coordinator = coordinator,
let currentItemId = currentItemId,
coordinator.sheetHost?.itemId == currentItemId else { return }
self.item = nil
if coordinator.sheetHost?.presentingViewController == nil {
onDismiss?()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment