Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to choose background interaction mode (.dismiss / .forward or .none) #115

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions PanModal/Controller/PanModalPresentationController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,21 @@ open class PanModalPresentationController: UIPresentationController {
} else {
view = DimmedView()
}
view.didTap = { [weak self] _ in
if self?.presentable?.allowsTapToDismiss == true {
self?.presentedViewController.dismiss(animated: true)

if let backgroundInteraction = self.presentable?.backgroundInteraction {
switch backgroundInteraction {
case .forward:
view.hitTestHandler = { [weak self] (point, event) in
return self?.presentingViewController.view.hitTest(point, with: event)
}

case .dismiss:
view.didTap = { [weak self] _ in
self?.presentedViewController.dismiss(animated: true)
}

default:
break
}
}
return view
Expand Down
23 changes: 23 additions & 0 deletions PanModal/Presentable/PanModalBackgroundInteraction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// PanModelBackgroundInteraction.swift
// PanModal
//
// Created by Ilya Kharlamov on 19.08.2020.
// Copyright © 2020 Detail. All rights reserved.
//

import Foundation

/** Describes the user interaction events that are triggered as the user taps the background */
public enum PanModalBackgroundInteraction: Equatable {

/** Taps dismiss the modal immediately */
case dismiss

/** Touches are forwarded to the lower window (In most cases it would be the application main window that will handle it */
case forward

/** Absorbs touches. The modal does nothing (Swallows the touch) */
case none

}
4 changes: 4 additions & 0 deletions PanModal/Presentable/PanModalPresentable+Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public extension PanModalPresentable where Self: UIViewController {
var allowsTapToDismiss: Bool {
return true
}

var backgroundInteraction: PanModalBackgroundInteraction {
return self.allowsTapToDismiss ? .dismiss : .none
}

var isUserInteractionEnabled: Bool {
return true
Expand Down
9 changes: 9 additions & 0 deletions PanModal/Presentable/PanModalPresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,19 @@ public protocol PanModalPresentable: AnyObject {
/**
A flag to determine if dismissal should be initiated when tapping on the dimmed background view.

- Note: This parameter id deprecated. Use `backgroundInteraction` instead.

Default value is true.
*/
var allowsTapToDismiss: Bool { get }

/**
Describes what happens when the user interacts the background view.

Default value is .dismiss.
*/
var backgroundInteraction: PanModalBackgroundInteraction { get }

/**
A flag to toggle user interactions on the container view.

Expand Down
22 changes: 19 additions & 3 deletions PanModal/View/DimmedView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,24 @@ public class DimmedView: UIView {
}
}
}

/**
The closure to be executed on hitTest
*/
var hitTestHandler: ((_ point: CGPoint, _ event: UIEvent?) -> UIView?)?

/**
The closure to be executed when a tap occurs
*/
var didTap: ((_ recognizer: UIGestureRecognizer) -> Void)?
var didTap: ((_ recognizer: UIGestureRecognizer) -> Void)? {
didSet {
if self.didTap != nil {
addGestureRecognizer(tapGesture)
} else {
removeGestureRecognizer(tapGesture)
}
}
}

/**
Tap gesture recognizer
Expand All @@ -59,15 +72,18 @@ public class DimmedView: UIView {
super.init(frame: .zero)
alpha = 0.0
backgroundColor = dimColor
addGestureRecognizer(tapGesture)
}

required public init?(coder aDecoder: NSCoder) {
fatalError()
}

// MARK: - Event Handlers


public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
return self.hitTestHandler?(point, event) ?? super.hitTest(point, with: event)
}

@objc private func didTapView() {
didTap?(tapGesture)
}
Expand Down
4 changes: 4 additions & 0 deletions PanModalDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
DC3B2EBE222A58C9000C8A4A /* AlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3B2EBD222A58C9000C8A4A /* AlertView.swift */; };
DCA741AE216D90410021F2F2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA741AD216D90410021F2F2 /* AppDelegate.swift */; };
DCC0EE7C21917F2500208DBC /* PanModalPresentable+Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC0EE7B21917F2500208DBC /* PanModalPresentable+Defaults.swift */; };
F31828BE24ED570600E3867B /* PanModalBackgroundInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = F31828BD24ED570600E3867B /* PanModalBackgroundInteraction.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -130,6 +131,7 @@
DCA741AD216D90410021F2F2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DCA741B9216D90420021F2F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DCC0EE7B21917F2500208DBC /* PanModalPresentable+Defaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PanModalPresentable+Defaults.swift"; sourceTree = "<group>"; };
F31828BD24ED570600E3867B /* PanModalBackgroundInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanModalBackgroundInteraction.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -300,6 +302,7 @@
isa = PBXGroup;
children = (
74C072A4220BA76D00124CE1 /* PanModalHeight.swift */,
F31828BD24ED570600E3867B /* PanModalBackgroundInteraction.swift */,
DC139068216D9458007A3E64 /* PanModalPresentable.swift */,
DCC0EE7B21917F2500208DBC /* PanModalPresentable+Defaults.swift */,
DC139069216D9458007A3E64 /* PanModalPresentable+UIViewController.swift */,
Expand Down Expand Up @@ -531,6 +534,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F31828BE24ED570600E3867B /* PanModalBackgroundInteraction.swift in Sources */,
0F2A2C5E2239C137003BDB2F /* PanModalAnimator.swift in Sources */,
0F2A2C5F2239C139003BDB2F /* PanModalPresentationAnimator.swift in Sources */,
0F2A2C602239C13C003BDB2F /* PanModalPresentationController.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Tests/PanModalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class PanModalTests: XCTestCase {
XCTAssertEqual(vc.allowsExtendedPanScrolling, false)
XCTAssertEqual(vc.allowsDragToDismiss, true)
XCTAssertEqual(vc.allowsTapToDismiss, true)
XCTAssertEqual(vc.backgroundInteraction, PanModalBackgroundInteraction.dismiss)
XCTAssertEqual(vc.isUserInteractionEnabled, true)
XCTAssertEqual(vc.isHapticFeedbackEnabled, true)
XCTAssertEqual(vc.shouldRoundTopCorners, false)
Expand Down