DismissibleHostingController.swift 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. //
  2. // DismissibleHostingController.swift
  3. // LoopKitUI
  4. //
  5. // Created by Michael Pangburn on 5/7/20.
  6. // Copyright © 2020 LoopKit Authors. All rights reserved.
  7. //
  8. import SwiftUI
  9. public class DismissibleHostingController: UIHostingController<AnyView> {
  10. public enum DismissalMode {
  11. case modalDismiss
  12. case pop(to: UIViewController.Type)
  13. }
  14. private var onDisappear: () -> Void = {}
  15. public convenience init<Content: View> (
  16. rootView: Content,
  17. dismissalMode: DismissalMode = .modalDismiss,
  18. isModalInPresentation: Bool = true,
  19. onDisappear: @escaping () -> Void = {},
  20. colorPalette: LoopUIColorPalette
  21. ) {
  22. self.init(rootView: rootView,
  23. dismissalMode: dismissalMode,
  24. isModalInPresentation: isModalInPresentation,
  25. onDisappear: onDisappear,
  26. guidanceColors: colorPalette.guidanceColors,
  27. carbTintColor: colorPalette.carbTintColor,
  28. glucoseTintColor: colorPalette.glucoseTintColor,
  29. insulinTintColor: colorPalette.insulinTintColor)
  30. }
  31. public convenience init<Content: View>(
  32. rootView: Content,
  33. dismissalMode: DismissalMode = .modalDismiss,
  34. isModalInPresentation: Bool = true,
  35. onDisappear: @escaping () -> Void = {},
  36. guidanceColors: GuidanceColors = GuidanceColors(),
  37. carbTintColor: Color = .green,
  38. glucoseTintColor: Color = Color(.systemTeal),
  39. insulinTintColor: Color = .orange
  40. ) {
  41. // Delay initialization of dismissal closure pushed into SwiftUI Environment until after calling the designated initializer
  42. var dismiss = {}
  43. self.init(rootView: AnyView(rootView.environment(\.dismissAction, { dismiss() })
  44. .environment(\.guidanceColors, guidanceColors)
  45. .environment(\.carbTintColor, carbTintColor)
  46. .environment(\.glucoseTintColor, glucoseTintColor)
  47. .environment(\.insulinTintColor, insulinTintColor)))
  48. switch dismissalMode {
  49. case .modalDismiss:
  50. dismiss = { [weak self] in self?.dismiss(animated: true) }
  51. case .pop(to: let PredecessorViewController):
  52. dismiss = { [weak self] in
  53. guard
  54. let navigationController = self?.navigationController,
  55. let predecessor = navigationController.viewControllers.last(where: { $0.isKind(of: PredecessorViewController) })
  56. else {
  57. return
  58. }
  59. navigationController.popToViewController(predecessor, animated: true)
  60. }
  61. }
  62. self.onDisappear = onDisappear
  63. self.isModalInPresentation = isModalInPresentation
  64. }
  65. public override func viewWillDisappear(_ animated: Bool) {
  66. super.viewWillDisappear(animated)
  67. onDisappear()
  68. }
  69. }