From 194a197e8339684f3f9a7300a8442727f6cf5b0e Mon Sep 17 00:00:00 2001 From: Shin Yamamoto Date: Sat, 4 May 2019 14:46:39 +0900 Subject: [PATCH 1/6] Fix a scroll lock after moving a panel --- Framework/Sources/FloatingPanel.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Framework/Sources/FloatingPanel.swift b/Framework/Sources/FloatingPanel.swift index a80efac..20f1611 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?() } } @@ -869,6 +869,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 From d25bc582490f25379e4c05789c39e1ccd49ec325 Mon Sep 17 00:00:00 2001 From: Shin Yamamoto Date: Sat, 4 May 2019 14:49:08 +0900 Subject: [PATCH 2/6] Add a sample for tap-to-move --- Examples/Samples/Sources/ViewController.swift | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Examples/Samples/Sources/ViewController.swift b/Examples/Samples/Sources/ViewController.swift index 7a5433d..d254620 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,6 +164,16 @@ class SampleListViewController: UIViewController { mainPanelVC.addPanel(toParent: self, belowView: nil, animated: true) } + @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 dismissDetailPanelVC() { detailPanelVC.removePanelFromParent(animated: true, completion: nil) } @@ -533,7 +548,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 +666,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 +682,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 [ From 39dfdd0ef02a71dfa301e21d50fa8f0b6824e4aa Mon Sep 17 00:00:00 2001 From: Shin Yamamoto Date: Sat, 4 May 2019 14:50:08 +0900 Subject: [PATCH 3/6] Remove an unused code --- Examples/Samples/Sources/ViewController.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Examples/Samples/Sources/ViewController.swift b/Examples/Samples/Sources/ViewController.swift index d254620..2154bc5 100644 --- a/Examples/Samples/Sources/ViewController.swift +++ b/Examples/Samples/Sources/ViewController.swift @@ -174,10 +174,6 @@ class SampleListViewController: UIViewController { } } - @objc func dismissDetailPanelVC() { - detailPanelVC.removePanelFromParent(animated: true, completion: nil) - } - @objc func handleBackdrop(tapGesture: UITapGestureRecognizer) { switch tapGesture.view { case mainPanelVC.backdropView: From c15d4c9035629eac0c80ef763d3c966251426369 Mon Sep 17 00:00:00 2001 From: Shin Yamamoto Date: Sat, 4 May 2019 14:55:25 +0900 Subject: [PATCH 4/6] Fix the moving animation's interruption --- Framework/Sources/FloatingPanel.swift | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Framework/Sources/FloatingPanel.swift b/Framework/Sources/FloatingPanel.swift index 20f1611..cff7a4e 100644 --- a/Framework/Sources/FloatingPanel.swift +++ b/Framework/Sources/FloatingPanel.swift @@ -310,13 +310,15 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate // 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 + let surfaceFrame = surfaceView.layer.presentation()?.frame ?? surfaceView.frame + guard fabs(surfaceFrame.minY - layoutAdapter.topY) > 10.0 else { + return } + 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 { From ec0e8cbdafd8256b2bb462662508b61bd80300f7 Mon Sep 17 00:00:00 2001 From: Shin Yamamoto Date: Sat, 4 May 2019 15:40:19 +0900 Subject: [PATCH 5/6] Avoid any tap gesture recognition while dragging a panel --- Framework/Sources/FloatingPanel.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Framework/Sources/FloatingPanel.swift b/Framework/Sources/FloatingPanel.swift index cff7a4e..aad9003 100644 --- a/Framework/Sources/FloatingPanel.swift +++ b/Framework/Sources/FloatingPanel.swift @@ -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) } } From 652ae8c967ddf7be287440d26ec06d17b3b32fea Mon Sep 17 00:00:00 2001 From: Shin Yamamoto Date: Sat, 4 May 2019 16:13:00 +0900 Subject: [PATCH 6/6] Remove a condition to prevent animation cancel Because I can't confirm any effect to fix that selecting a table view cell sometimes isn't working after flicking to half from full. --- Framework/Sources/FloatingPanel.swift | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Framework/Sources/FloatingPanel.swift b/Framework/Sources/FloatingPanel.swift index aad9003..2420308 100644 --- a/Framework/Sources/FloatingPanel.swift +++ b/Framework/Sources/FloatingPanel.swift @@ -308,13 +308,6 @@ 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. - let surfaceFrame = surfaceView.layer.presentation()?.frame ?? surfaceView.frame - guard fabs(surfaceFrame.minY - layoutAdapter.topY) > 10.0 else { - return - } if animator.isInterruptible { animator.stopAnimation(false) animator.finishAnimation(at: .current)