diff --git a/PanModal/View/PanContainerView.swift b/PanModal/View/PanContainerView.swift index f5c2892b..665a613f 100644 --- a/PanModal/View/PanContainerView.swift +++ b/PanModal/View/PanContainerView.swift @@ -15,10 +15,13 @@ import UIKit having to do those changes directly on the view */ class PanContainerView: UIView { + + private weak var presentedViewController: UIViewController? init(presentedView: UIView, frame: CGRect) { super.init(frame: frame) addSubview(presentedView) + presentedViewController = presentedView.parentViewController } @available(*, unavailable) @@ -26,6 +29,20 @@ class PanContainerView: UIView { fatalError("init(coder:) has not been implemented") } + override func accessibilityPerformEscape() -> Bool { + var shouldPerforEscape: Bool = true + if let panModalPresentable = presentedViewController as? PanModalPresentable { + shouldPerforEscape = panModalPresentable.allowsDragToDismiss || panModalPresentable.allowsTapToDismiss + presentedViewController?.dismiss(animated: true, completion: nil) + } + return shouldPerforEscape + } +} + +private extension UIResponder { + var parentViewController: UIViewController? { + return next as? UIViewController ?? next?.parentViewController + } } extension UIView { diff --git a/Tests/UIAccessiblityPerformEscapeTests.swift b/Tests/UIAccessiblityPerformEscapeTests.swift new file mode 100644 index 00000000..9502fc79 --- /dev/null +++ b/Tests/UIAccessiblityPerformEscapeTests.swift @@ -0,0 +1,43 @@ +// +// UIAccessiblityPerformEscapeTests.swift +// PanModalTests +// +// Created by Sungdoo on 2022/03/17. +// Copyright © 2022 Detail. All rights reserved. +// + +import XCTest +import PanModal + +class UIAccessiblityPerformEscapeTests: XCTestCase { + + class MockViewController: UIViewController, PanModalPresentable { + var panScrollable: UIScrollView? { return nil } + } + + func testAccessibilityPerformEscape() throws { + + let presenterViewController = UIApplication.shared.keyWindow?.rootViewController + let panModal: UIViewController & PanModalPresentable = MockViewController() + + presenterViewController?.presentPanModal(panModal) + XCTAssertNotNil(presenterViewController?.presentedViewController, "panModal should have been presented") + + let presentDidFisnish = XCTestExpectation() + let dismissDidFinish = XCTestExpectation() + + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + + let panContainerView = panModal.view.superview + presentDidFisnish.fulfill() + + panContainerView?.accessibilityPerformEscape() + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + XCTAssertNil(presenterViewController?.presentedViewController, "panModal should have been dismissed") + dismissDidFinish.fulfill() + } + } + + wait(for: [presentDidFisnish, dismissDidFinish], timeout: 10) + } +}