diff --git a/Examples/Samples/Sources/ViewController.swift b/Examples/Samples/Sources/ViewController.swift index 7a5433d..2154bc5 100644 --- a/Examples/Samples/Sources/ViewController.swift +++ b/Examples/Samples/Sources/ViewController.swift @@ -129,6 +129,11 @@ class SampleListViewController: UIViewController { // Enable tap-to-hide and removal interaction switch currentMenu { + case .trackingTableView: + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSurface(tapGesture:))) + tapGesture.cancelsTouchesInView = false + tapGesture.numberOfTapsRequired = 2 + mainPanelVC.surfaceView.addGestureRecognizer(tapGesture) case .showRemovablePanel, .showIntrinsicView: mainPanelVC.isRemovalInteractionEnabled = true @@ -159,8 +164,14 @@ class SampleListViewController: UIViewController { mainPanelVC.addPanel(toParent: self, belowView: nil, animated: true) } - @objc func dismissDetailPanelVC() { - detailPanelVC.removePanelFromParent(animated: true, completion: nil) + @objc + func handleSurface(tapGesture: UITapGestureRecognizer) { + switch mainPanelVC.position { + case .full: + mainPanelVC.move(to: .half, animated: true) + default: + mainPanelVC.move(to: .full, animated: true) + } } @objc func handleBackdrop(tapGesture: UITapGestureRecognizer) { @@ -533,7 +544,7 @@ class InspectableViewController: UIViewController { } } -class DebugTableViewController: InspectableViewController, UITableViewDataSource, UITableViewDelegate { +class DebugTableViewController: InspectableViewController { weak var tableView: UITableView! var items: [String] = [] var itemHeight: CGFloat = 66.0 @@ -651,7 +662,9 @@ class DebugTableViewController: InspectableViewController, UITableViewDataSource // Remove FloatingPanel from a view (self.parent as! FloatingPanelController).removePanelFromParent(animated: true, completion: nil) } +} +extension DebugTableViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } @@ -665,6 +678,12 @@ class DebugTableViewController: InspectableViewController, UITableViewDataSource cell.textLabel?.text = items[indexPath.row] return cell } +} + +extension DebugTableViewController: UITableViewDelegate { + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + print("DebugTableViewController -- select row \(indexPath.row)") + } func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { return [ diff --git a/Framework/Sources/FloatingPanel.swift b/Framework/Sources/FloatingPanel.swift index 04687a1..ecbff73 100644 --- a/Framework/Sources/FloatingPanel.swift +++ b/Framework/Sources/FloatingPanel.swift @@ -21,8 +21,6 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate didSet { guard let scrollView = scrollView else { return } scrollView.panGestureRecognizer.addTarget(self, action: #selector(handle(panGesture:))) - scrollBouncable = scrollView.bounces - scrollIndictorVisible = scrollView.showsVerticalScrollIndicator } } @@ -124,6 +122,7 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate animator.addCompletion { [weak self] _ in guard let `self` = self else { return } self.animator = nil + self.unlockScrollView() completion?() } self.animator = animator @@ -131,6 +130,7 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate } else { self.state = to self.updateLayout(to: to) + self.unlockScrollView() completion?() } } @@ -181,8 +181,9 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate // and handle them in self.handle(panGesture:) return scrollView?.gestureRecognizers?.contains(otherGestureRecognizer) ?? false default: - // Should always recognize tap/long press gestures in parallel - return true + // Should recognize tap/long press gestures in parallel when the surface view is at an anchor position. + let surfaceFrame = surfaceView.layer.presentation()?.frame ?? surfaceView.frame + return surfaceFrame.minY == layoutAdapter.positionY(for: state) } } @@ -307,16 +308,11 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate if let animator = self.animator { log.debug("panel animation interrupted!!!") - // Prevent aborting touch events when the current animator is - // released almost at a target position. Because any tap gestures - // shouldn't be disturbed at the position. - if fabs(surfaceView.frame.minY - layoutAdapter.topY) > 40.0 { - if animator.isInterruptible { - animator.stopAnimation(false) - animator.finishAnimation(at: .current) - } - self.animator = nil + if animator.isInterruptible { + animator.stopAnimation(false) + animator.finishAnimation(at: .current) } + self.animator = nil // A user can stop a panel at the nearest Y of a target position if abs(surfaceView.frame.minY - layoutAdapter.topY) < 1.0 { @@ -869,6 +865,9 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate private func lockScrollView() { guard let scrollView = scrollView else { return } + scrollBouncable = scrollView.bounces + scrollIndictorVisible = scrollView.showsVerticalScrollIndicator + scrollView.isDirectionalLockEnabled = true scrollView.bounces = false scrollView.showsVerticalScrollIndicator = false