Skip to content

Commit

Permalink
Always present fixed height sheet on top controller and deley present…
Browse files Browse the repository at this point in the history
…ing 100 milli to avoid presenting on a dimissed controller
  • Loading branch information
MalekKamel committed Mar 8, 2023
1 parent e32aa6b commit 8bd8601
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 122 deletions.
14 changes: 4 additions & 10 deletions Demo/Screens/Home/HomeScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,23 +135,17 @@ struct HomeScreen: View {
ForEach(items, id: \.uuid) { item in
NavLink(
destination: ProductDetailScreen.build(item: item),
type: vm.navigationOption,
onDismissSheet: {
print("Sheet dismissed.")
}) {
type: vm.navigationOption) {
// When this view is clicked, it will trigger the navigation
ProductItemView(item: item)
}
.buttonStyle(PlainButtonStyle())

// It's also possible to use Navigator object directly to navigate
if false {
ProductItemView(item: item).onTapGesture {
navigator.navigate(
type: vm.navigationOption,
onDismissSheet: {
print("Sheet dismissed.")
}) {
ProductItemView(item: item)
.onTapGesture {
navigator.navigate(type: vm.navigationOption) {
ProductDetailScreen(item: item)
}
}
Expand Down
7 changes: 1 addition & 6 deletions SwiftUINavigator/Sources/SwiftUINavigator/NavLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,21 @@ public struct NavLink<Destination: View, Label: View>: View {
private let destination: () -> Destination
private let type: NavType
private let label: () -> Label
private let onDismissSheet: (() -> Void)?
@EnvironmentObject private var navigator: Navigator

public init(
destination: @escaping @autoclosure () -> Destination,
type: NavType = .push(),
onDismissSheet: (() -> Void)? = nil,
label: @escaping () -> Label) {
self.destination = destination
self.type = type
self.label = label
self.onDismissSheet = onDismissSheet
}

public var body: some View {
label()
.onTapGesture {
navigator.navigate(
type: type,
onDismissSheet: onDismissSheet) {
navigator.navigate(type: type) {
destination()
}
}
Expand Down
8 changes: 1 addition & 7 deletions SwiftUINavigator/Sources/SwiftUINavigator/NavManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,7 @@ class NavManager: ObservableObject {

extension NavManager {

func navigate<Element: View>(
_ element: Element,
type: NavType,
onDismissSheet: (() -> Void)?) {
func navigate<Element: View>(_ element: Element, type: NavType) {
switch type {
case let .push(id, addToBackStack, showDefaultNavBar):
push(
Expand All @@ -103,7 +100,6 @@ extension NavManager {
case .sheet(let type):
sheetManager.presentSheet(
type: type,
onDismiss: nil,
content: { element })
case let .dialog(dismissOnTouchOutside, presenter):
presentDialog(
Expand All @@ -115,11 +111,9 @@ extension NavManager {

func presentSheet<Content: View>(
type: SheetType,
onDismiss: (() -> Void)?,
content: () -> Content) {
sheetManager.presentSheet(
type: type,
onDismiss: onDismiss,
content: content)
}

Expand Down
8 changes: 1 addition & 7 deletions SwiftUINavigator/Sources/SwiftUINavigator/Navigator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,8 @@ public class Navigator: ObservableObject {
/// - element: the view
public func navigate<Element: View>(
type: NavType = .push(),
onDismissSheet: (() -> Void)? = nil,
_ element: () -> Element) {
manager.navigate(
element(),
type: type,
onDismissSheet: onDismissSheet)
manager.navigate(element(), type: type)
}

/// Navigates to a view.
Expand All @@ -50,11 +46,9 @@ public class Navigator: ObservableObject {
/// - content: the view.
public func presentSheet<Content: View>(
type: SheetType,
onDismiss: (() -> Void)? = nil,
content: () -> Content) {
manager.presentSheet(
type: type,
onDismiss: onDismiss,
content: content)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ struct FixedHeightSheetView<Content: View>: View {
@Environment(\.presentationMode) var presentationMode
private var content: Content
private let isDismissable: Bool
private let presenter: FixedSheetPresenter
@State private var isContentVisible: Bool = false

init(presenter: FixedSheetPresenter, isDismissable: Bool, @ViewBuilder content: @escaping () -> Content) {
init(isDismissable: Bool,
@ViewBuilder content: @escaping () -> Content) {
self.content = content()
self.presenter = presenter
self.isDismissable = isDismissable
}

Expand All @@ -26,8 +25,7 @@ struct FixedHeightSheetView<Content: View>: View {
guard isDismissable else {
return
}
presenter.controller?.dismiss(animated: false)
FixedSheetPresenter.current = .rootController
UIApplication.shared.topViewController()?.dismiss(animated: false)
}
.animation(.easeInOut)
content.transition(.move(edge: .bottom))
Expand All @@ -44,13 +42,16 @@ struct FixedHeightSheetView<Content: View>: View {


func presentSheetController<Content: View>(
presenter: FixedSheetPresenter,
isDismissable: Bool,
content: Content) {
let view = FixedHeightSheetView(presenter: presenter, isDismissable: isDismissable) {
let view = FixedHeightSheetView(
isDismissable: isDismissable
) {
content
}
let controller = SheetController(rootView: view)
presenter.controller?.present(controller, animated: false)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
UIApplication.shared.topViewController()?.present(controller, animated: false)
}
}
#endif
43 changes: 7 additions & 36 deletions SwiftUINavigator/Sources/SwiftUINavigator/Sheet/SheetManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,9 @@ import SwiftUI
class SheetManager: ObservableObject {
var navManager: NavManager!

@Published var presentSheet: Bool = false {
didSet {
if !presentSheet {
onDismissSheet?()
onDismissSheet = nil
}
}
}
@Published var presentFullSheet: Bool = false {
didSet {
if !presentFullSheet {
onDismissSheet?()
onDismissSheet = nil
}
}
}
@Published var presentFixedHeightSheet: Bool = false {
didSet {
if !presentFixedHeightSheet {
onDismissSheet?()
onDismissSheet = nil
}
}
}
private var onDismissSheet: (() -> Void)? = nil
@Published var presentSheet: Bool = false
@Published var presentFullSheet: Bool = false
@Published var presentFixedHeightSheet: Bool = false
var sheet: AnyView? = nil
var sheetArgs = SheetArguments(
height: 0,
Expand All @@ -42,9 +20,7 @@ extension SheetManager {

func presentSheet<Content: View>(
type: SheetType,
onDismiss: (() -> Void)?,
content: () -> Content) {
onDismissSheet = onDismiss
switch type {
#if os(iOS)
case .normal:
Expand Down Expand Up @@ -103,24 +79,20 @@ extension SheetManager {
#endif

#if os(iOS)
case let .fixedHeight(type, isDismissable, presenter):
FixedSheetPresenter.current = presenter
case let .fixedHeight(type, isDismissable):
presentFixedSheet(
height: type.height,
isDismissable: isDismissable,
presenter: presenter)
isDismissable: isDismissable)
#endif
}
}

private func presentFixedSheet(
height: CGFloat,
isDismissable: Bool,
presenter: FixedSheetPresenter) {
isDismissable: Bool) {
presentFixedHeightSheet = true
withAnimation(navManager.options.easeAnimation) {
presentSheetController(
presenter: presenter,
isDismissable: isDismissable,
content: sheet?.frame(height: height)
)
Expand Down Expand Up @@ -161,8 +133,7 @@ extension SheetManager {

private func dismissFixedSheet() {
#if os(iOS)
FixedSheetPresenter.current.controller?.dismiss(animated: false)
FixedSheetPresenter.current = .rootController
UIApplication.shared.topViewController()?.dismiss(animated: false)
#endif
}
}
26 changes: 1 addition & 25 deletions SwiftUINavigator/Sources/SwiftUINavigator/Sheet/SheetType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ public enum SheetType {
#endif

@available(macOS, unavailable)
case fixedHeight(
FixedHeightType,
isDismissable: Bool = true,
presenter: FixedSheetPresenter = .rootController)
case fixedHeight(FixedHeightType, isDismissable: Bool = true)
}

public enum FixedHeightType {
Expand All @@ -46,27 +43,6 @@ public enum FixedHeightType {
}
}

public enum FixedSheetPresenter {
case rootController
case topController
#if os(iOS)
case controller(UIViewController)

public var controller: UIViewController? {
switch self {
case .rootController:
return UIApplication.shared.rootController
case .topController:
return UIApplication.shared.topViewController()
case .controller(let controller):
return controller
}
}
#endif

static var current: FixedSheetPresenter = .rootController
}

public enum DismissSheetType {
case normal
case full
Expand Down
29 changes: 6 additions & 23 deletions SwiftUINavigatorTests/NavManagerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,49 +46,32 @@ class NavManagerTests: XCTestCase {
}

func testNavigate_push_stackItemsShouldBeNotEmpty() throws {
manager.navigate(
EmptyView(),
type: .push(),
onDismissSheet: {})
manager.navigate(EmptyView(), type: .push())
XCTAssertFalse(manager.stackItems.isEmpty)
}

func testNavigate_sheet_normal_shouldBePresented() throws {
manager.navigate(
EmptyView(),
type: .sheet(type: .normal),
onDismissSheet: {})
manager.navigate(EmptyView(), type: .sheet(type: .normal))
XCTAssertTrue(sheetManager.presentSheet)
}

func testNavigate_sheet_full_shouldBePresented() throws {
manager.navigate(
EmptyView(),
type: .sheet(type: .full),
onDismissSheet: {})
manager.navigate(EmptyView(), type: .sheet(type: .full))
XCTAssertTrue(sheetManager.presentFullSheet)
}

func testNavigate_sheet_fixedHeight_shouldBePresented() throws {
manager.navigate(
EmptyView(),
type: .sheet(type: .fixedHeight(.value(0))),
onDismissSheet: {})
manager.navigate(EmptyView(), type: .sheet(type: .fixedHeight(.value(0))))
XCTAssertTrue(sheetManager.presentFixedHeightSheet)
}

func testNavigate_dialog_shouldBePresented() throws {
manager.navigate(
EmptyView(),
type: .dialog(),
onDismissSheet: {})
manager.navigate(EmptyView(), type: .dialog())
XCTAssertTrue(dialogManager.isPresented)
}

func testPresentSheet() throws {
manager.presentSheet(
type: .normal,
onDismiss: {}) {
manager.presentSheet(type: .normal) {
EmptyView()
}
XCTAssertTrue(sheetManager.presentSheet)
Expand Down

0 comments on commit 8bd8601

Please sign in to comment.