Skip to content

Commit 5083989

Browse files
author
Ivo Silva
committed
Background interaction from slackhq#115
1 parent 39fc420 commit 5083989

8 files changed

Lines changed: 74 additions & 4 deletions

File tree

PanModal/Controller/PanModalPresentationController.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,20 @@ open class PanModalPresentationController: UIPresentationController {
117117
} else {
118118
view = DimmedView()
119119
}
120-
view.didTap = { [weak self] _ in
121-
if self?.presentable?.allowsTapToDismiss == true {
122-
self?.presentedViewController.dismiss(animated: true)
120+
if let backgroundInteraction = self.presentable?.backgroundInteraction {
121+
switch backgroundInteraction {
122+
case .forward:
123+
view.hitTestHandler = { [weak self] (point, event) in
124+
return self?.presentingViewController.view.hitTest(point, with: event)
125+
}
126+
127+
case .dismiss:
128+
view.didTap = { [weak self] _ in
129+
self?.presentedViewController.dismiss(animated: true)
130+
}
131+
132+
default:
133+
break
123134
}
124135
}
125136
return view
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// PanModelBackgroundInteraction.swift
3+
// PanModal
4+
//
5+
// Created by Ilya Kharlamov on 19.08.2020.
6+
// Copyright © 2020 Detail. All rights reserved.
7+
//
8+
import Foundation
9+
10+
/** Describes the user interaction events that are triggered as the user taps the background */
11+
public enum PanModalBackgroundInteraction: Equatable {
12+
13+
/** Taps dismiss the modal immediately */
14+
case dismiss
15+
16+
/** Touches are forwarded to the lower window (In most cases it would be the application main window that will handle it */
17+
case forward
18+
19+
/** Absorbs touches. The modal does nothing (Swallows the touch) */
20+
case none
21+
22+
}

PanModal/Presentable/PanModalPresentable+Defaults.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ public extension PanModalPresentable where Self: UIViewController {
8585
return true
8686
}
8787

88+
var backgroundInteraction: PanModalBackgroundInteraction {
89+
return self.allowsTapToDismiss ? .dismiss : .none
90+
}
91+
8892
var isUserInteractionEnabled: Bool {
8993
return true
9094
}

PanModal/Presentable/PanModalPresentable.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ public protocol PanModalPresentable: AnyObject {
153153
*/
154154
var allowsTapToDismiss: Bool { get }
155155

156+
/**
157+
Describes what happens when the user interacts the background view.
158+
159+
Default value is .dismiss.
160+
*/
161+
var backgroundInteraction: PanModalBackgroundInteraction { get }
162+
156163
/**
157164
A flag to toggle user interactions on the container view.
158165

PanModal/View/DimmedView.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,24 @@ public class DimmedView: UIView {
4040
}
4141
}
4242
}
43+
44+
/**
45+
The closure to be executed on hitTest
46+
*/
47+
var hitTestHandler: ((_ point: CGPoint, _ event: UIEvent?) -> UIView?)?
4348

4449
/**
4550
The closure to be executed when a tap occurs
4651
*/
47-
var didTap: ((_ recognizer: UIGestureRecognizer) -> Void)?
52+
var didTap: ((_ recognizer: UIGestureRecognizer) -> Void)? {
53+
didSet {
54+
if self.didTap != nil {
55+
addGestureRecognizer(tapGesture)
56+
} else {
57+
removeGestureRecognizer(tapGesture)
58+
}
59+
}
60+
}
4861

4962
/**
5063
Tap gesture recognizer
@@ -67,6 +80,10 @@ public class DimmedView: UIView {
6780
}
6881

6982
// MARK: - Event Handlers
83+
84+
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
85+
return self.hitTestHandler?(point, event) ?? super.hitTest(point, with: event)
86+
}
7087

7188
@objc private func didTapView() {
7289
didTap?(tapGesture)

PanModalDemo.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
0F2A2C682239C15D003BDB2F /* UIViewController+PanModalPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74C072A9220BA82A00124CE1 /* UIViewController+PanModalPresenter.swift */; };
2424
0F2A2C692239C162003BDB2F /* DimmedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC13906E216D9458007A3E64 /* DimmedView.swift */; };
2525
0F2A2C6A2239C165003BDB2F /* PanContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94795C9C21F03368008045A0 /* PanContainerView.swift */; };
26+
48EE033725FA8E160069DE6C /* PanModalBackgroundInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48EE033625FA8E160069DE6C /* PanModalBackgroundInteraction.swift */; };
27+
48EE034025FA8E320069DE6C /* PanModalBackgroundInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48EE033625FA8E160069DE6C /* PanModalBackgroundInteraction.swift */; };
2628
743CABB02225FC9F00634A5A /* UserGroupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 743CABAF2225FC9F00634A5A /* UserGroupViewController.swift */; };
2729
743CABB22225FD1100634A5A /* UserGroupHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 743CABB12225FD1100634A5A /* UserGroupHeaderView.swift */; };
2830
743CABB42225FE7700634A5A /* UserGroupMemberPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 743CABB32225FE7700634A5A /* UserGroupMemberPresentable.swift */; };
@@ -93,6 +95,7 @@
9395
0F2A2C512239C119003BDB2F /* PanModal.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PanModal.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9496
0F2A2C532239C119003BDB2F /* PanModal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PanModal.h; sourceTree = "<group>"; };
9597
0F2A2C542239C119003BDB2F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
98+
48EE033625FA8E160069DE6C /* PanModalBackgroundInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanModalBackgroundInteraction.swift; sourceTree = "<group>"; };
9699
743CABAF2225FC9F00634A5A /* UserGroupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserGroupViewController.swift; sourceTree = "<group>"; };
97100
743CABB12225FD1100634A5A /* UserGroupHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserGroupHeaderView.swift; sourceTree = "<group>"; };
98101
743CABB32225FE7700634A5A /* UserGroupMemberPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserGroupMemberPresentable.swift; sourceTree = "<group>"; };
@@ -300,6 +303,7 @@
300303
isa = PBXGroup;
301304
children = (
302305
74C072A4220BA76D00124CE1 /* PanModalHeight.swift */,
306+
48EE033625FA8E160069DE6C /* PanModalBackgroundInteraction.swift */,
303307
DC139068216D9458007A3E64 /* PanModalPresentable.swift */,
304308
DCC0EE7B21917F2500208DBC /* PanModalPresentable+Defaults.swift */,
305309
DC139069216D9458007A3E64 /* PanModalPresentable+UIViewController.swift */,
@@ -540,6 +544,7 @@
540544
0F2A2C642239C14E003BDB2F /* PanModalPresentable+Defaults.swift in Sources */,
541545
0F2A2C652239C151003BDB2F /* PanModalPresentable+UIViewController.swift in Sources */,
542546
0F2A2C662239C153003BDB2F /* PanModalPresentable+LayoutHelpers.swift in Sources */,
547+
48EE033725FA8E160069DE6C /* PanModalBackgroundInteraction.swift in Sources */,
543548
0F2A2C672239C157003BDB2F /* PanModalPresenter.swift in Sources */,
544549
0F2A2C682239C15D003BDB2F /* UIViewController+PanModalPresenter.swift in Sources */,
545550
0F2A2C692239C162003BDB2F /* DimmedView.swift in Sources */,
@@ -587,6 +592,7 @@
587592
743CABD322265F2E00634A5A /* ProfileViewController.swift in Sources */,
588593
DC139070216D9458007A3E64 /* PanModalPresentationAnimator.swift in Sources */,
589594
944EBA2E227BB7F400C4C97B /* FullScreenNavController.swift in Sources */,
595+
48EE034025FA8E320069DE6C /* PanModalBackgroundInteraction.swift in Sources */,
590596
DCA741AE216D90410021F2F2 /* AppDelegate.swift in Sources */,
591597
);
592598
runOnlyForDeploymentPostprocessing = 0;

Sample/View Controllers/User Groups/UserGroupViewController.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ class UserGroupViewController: UITableViewController, PanModalPresentable {
101101
return .contentHeight(300)
102102
}
103103

104+
var backgroundInteraction: PanModalBackgroundInteraction { .forward }
105+
104106
var scrollIndicatorInsets: UIEdgeInsets {
105107
let bottomOffset = presentingViewController?.bottomLayoutGuide.length ?? 0
106108
return UIEdgeInsets(top: headerView.frame.size.height, left: 0, bottom: bottomOffset, right: 0)

Tests/PanModalTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class PanModalTests: XCTestCase {
5555
XCTAssertEqual(vc.allowsExtendedPanScrolling, false)
5656
XCTAssertEqual(vc.allowsDragToDismiss, true)
5757
XCTAssertEqual(vc.allowsTapToDismiss, true)
58+
XCTAssertEqual(vc.backgroundInteraction, .dismiss)
5859
XCTAssertEqual(vc.isUserInteractionEnabled, true)
5960
XCTAssertEqual(vc.isHapticFeedbackEnabled, true)
6061
XCTAssertEqual(vc.shouldRoundTopCorners, false)

0 commit comments

Comments
 (0)