diff --git a/Sources/YBottomSheet/BottomSheetController+Appearance.swift b/Sources/YBottomSheet/BottomSheetController+Appearance.swift index dea86a0..e78cf1a 100644 --- a/Sources/YBottomSheet/BottomSheetController+Appearance.swift +++ b/Sources/YBottomSheet/BottomSheetController+Appearance.swift @@ -32,9 +32,11 @@ extension BottomSheetController { /// /// Only applicable for resizable sheets. `nil` means to use the content view's intrinsic height as the minimum. public var minimumContentHeight: CGFloat? - /// Whether the sheet is dismissible or not. Default is `true`. - public var allowDismiss: Bool - + /// Whether the sheet can be dismissed by swiping down or tapping on the dimmer. Default is `true`. + /// + /// The user can always dismiss the sheet from the close button if it is visible. + public var isDismissAllowed: Bool + /// Default appearance (fixed size sheet) public static let `default` = Appearance() /// Default appearance for a resizable sheet @@ -51,7 +53,7 @@ extension BottomSheetController { /// - presentAnimationCurve: Animaiton during presenting. /// - dismissAnimationCurve: Animation during dismiss. /// - minimumContentHeight: Optional) Minimum content view height. - /// - allowDismiss: Whether the sheet is dismissible or not. + /// - isDismissAllowed: Whether the sheet can be dismissed by swiping down or tapping on the dimmer. public init( indicatorAppearance: DragIndicatorView.Appearance? = nil, headerAppearance: SheetHeaderView.Appearance? = .default, @@ -62,7 +64,7 @@ extension BottomSheetController { presentAnimationCurve: UIView.AnimationOptions = .curveEaseIn, dismissAnimationCurve: UIView.AnimationOptions = .curveEaseOut, minimumContentHeight: CGFloat? = nil, - allowDismiss: Bool = true + isDismissAllowed: Bool = true ) { self.indicatorAppearance = indicatorAppearance self.headerAppearance = headerAppearance @@ -73,7 +75,7 @@ extension BottomSheetController { self.presentAnimationCurve = presentAnimationCurve self.dismissAnimationCurve = dismissAnimationCurve self.minimumContentHeight = minimumContentHeight - self.allowDismiss = allowDismiss + self.isDismissAllowed = isDismissAllowed } } } diff --git a/Sources/YBottomSheet/BottomSheetController.swift b/Sources/YBottomSheet/BottomSheetController.swift index 231e8a4..d108532 100644 --- a/Sources/YBottomSheet/BottomSheetController.swift +++ b/Sources/YBottomSheet/BottomSheetController.swift @@ -150,10 +150,11 @@ public class BottomSheetController: UIViewController { return true } - /// Dismiss bottom sheet. - /// - Parameter isCloseButton: whether close button is tapped or not. - func didDismiss(isCloseButton: Bool = false) { - if appearance.allowDismiss || isCloseButton { + /// Dismisses the bottom sheet if allowed. + /// + /// This method is not called when the header's close button is tapped. + func didDismiss() { + if appearance.isDismissAllowed { onDismiss() } } @@ -316,8 +317,9 @@ private extension BottomSheetController { extension BottomSheetController: SheetHeaderViewDelegate { @objc - func didCloseTapped() { - didDismiss(isCloseButton: true) + func didTapCloseButton() { + // Directly dismiss the sheet without considering `isDismissAllowed`. + onDismiss() } } @@ -382,6 +384,6 @@ internal extension BottomSheetController { @objc func simulateDismiss() { - didCloseTapped() + didTapCloseButton() } } diff --git a/Sources/YBottomSheet/Protocols/SheetHeaderViewDelegate.swift b/Sources/YBottomSheet/Protocols/SheetHeaderViewDelegate.swift index 3f6e395..cc16f53 100644 --- a/Sources/YBottomSheet/Protocols/SheetHeaderViewDelegate.swift +++ b/Sources/YBottomSheet/Protocols/SheetHeaderViewDelegate.swift @@ -9,5 +9,5 @@ import Foundation internal protocol SheetHeaderViewDelegate: AnyObject { - func didCloseTapped() + func didTapCloseButton() } diff --git a/Sources/YBottomSheet/SheetHeaderView/SheetHeaderView.swift b/Sources/YBottomSheet/SheetHeaderView/SheetHeaderView.swift index 8741b48..a46d0f8 100644 --- a/Sources/YBottomSheet/SheetHeaderView/SheetHeaderView.swift +++ b/Sources/YBottomSheet/SheetHeaderView/SheetHeaderView.swift @@ -51,7 +51,7 @@ open class SheetHeaderView: UIView { required public init?(coder: NSCoder) { nil } @objc private func closeButtonAction() { - delegate?.didCloseTapped() + delegate?.didTapCloseButton() } // For unit testing diff --git a/Tests/YBottomSheetTests/BottomSheetControllerTests.swift b/Tests/YBottomSheetTests/BottomSheetControllerTests.swift index ab4ae56..61f60c9 100644 --- a/Tests/YBottomSheetTests/BottomSheetControllerTests.swift +++ b/Tests/YBottomSheetTests/BottomSheetControllerTests.swift @@ -13,6 +13,7 @@ import YMatterType // OK to have lots of test cases // swiftlint:disable file_length +// swiftlint:disable type_body_length final class BottomSheetControllerTests: XCTestCase { var window: UIWindow! @@ -288,9 +289,7 @@ final class BottomSheetControllerTests: XCTestCase { let sut = makeSUT(viewController: UINavigationController(rootViewController: UIViewController())) XCTAssertFalse(sut.hasHeader) } -} -extension BottomSheetControllerTests { func test_onDimmer() { let sut = SpyBottomSheetController(title: "", childView: UIView()) @@ -327,16 +326,18 @@ extension BottomSheetControllerTests { func test_forbidDismiss() { let sut = SpyBottomSheetController(title: "", childView: UIView()) - sut.appearance.allowDismiss = false + sut.appearance.isDismissAllowed = false XCTAssertFalse(sut.onSwipeDown) XCTAssertFalse(sut.onDimmerTapped) + XCTAssertFalse(sut.isDismissed) sut.simulateOnDimmerTap() sut.simulateOnSwipeDown() XCTAssertFalse(sut.onSwipeDown) XCTAssertFalse(sut.onDimmerTapped) + XCTAssertFalse(sut.isDismissed) } } @@ -383,24 +384,29 @@ final class SpyBottomSheetController: BottomSheetController { var onSwipeDown = false var onDimmerTapped = false var onDragging = false + + override func simulateDismiss() { + super.simulateDismiss() + isDismissed = true + } - override func didDismiss(isCloseButton: Bool) { + override func didDismiss() { super.didDismiss() - if isCloseButton || appearance.allowDismiss { + if appearance.isDismissAllowed { isDismissed = true } } override func simulateOnSwipeDown() { super.simulateOnSwipeDown() - if appearance.allowDismiss { + if appearance.isDismissAllowed { onSwipeDown = true } } override func simulateOnDimmerTap() { super.simulateOnDimmerTap() - if appearance.allowDismiss { + if appearance.isDismissAllowed { onDimmerTapped = true } } diff --git a/Tests/YBottomSheetTests/SheetHeaderView/SheetHeaderViewTests.swift b/Tests/YBottomSheetTests/SheetHeaderView/SheetHeaderViewTests.swift index d73f4d5..3ee3d56 100644 --- a/Tests/YBottomSheetTests/SheetHeaderView/SheetHeaderViewTests.swift +++ b/Tests/YBottomSheetTests/SheetHeaderView/SheetHeaderViewTests.swift @@ -91,7 +91,7 @@ private extension SheetHeaderViewTests { } extension SheetHeaderViewTests: SheetHeaderViewDelegate { - func didCloseTapped() { + func didTapCloseButton() { isDismissed = true } }