Last active
October 11, 2021 01:06
-
-
Save edudnyk/ca6ce0064d4b3f4842524bc0a0ca15fa to your computer and use it in GitHub Desktop.
Initial sandwich solution implementation in SheeKit
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
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