Compare commits

..

11 Commits

Author SHA1 Message Date
Shin Yamamoto 47971f607a Release v1.2.1 2018-11-26 09:40:14 +09:00
Shin Yamamoto 03a4d342a3 Merge pull request #66 from Galeas/fix-remove-backdrop-view-on-dismiss
Fix remove backdrop view on dismiss
2018-11-25 11:11:22 +09:00
Evgeniy Branitsky 4f5abfefec Removing backdrop view 2018-11-24 11:21:56 +03:00
Shin Yamamoto e1ee3c06e8 Merge pull request #62 from SCENEE/feat-make-animator-interruptible
Make the animated interaction interruptible
2018-11-22 20:21:11 +09:00
Shin Yamamoto 17ba704472 Make the animated interaction interruptible 2018-11-22 14:26:18 +09:00
Shin Yamamoto e5391fa1f4 Merge pull request #61 from SCENEE/improve-delegate
Improve delegate
2018-11-22 13:54:02 +09:00
Shin Yamamoto c0647017b5 Add FloatingPanelControllerDelegate.floatingPanelDidChangePosition(_:) 2018-11-21 09:10:50 +09:00
Shin Yamamoto 3686bb4b44 Clean up code for scrollGestureRecognizers 2018-11-20 11:08:23 +09:00
Shin Yamamoto 76c8ca4b20 Merge pull request #56 from SCENEE/fix-gesture-handling
Fix the gesture handling
2018-11-20 11:07:14 +09:00
Shin Yamamoto c53e64027b Merge pull request #45 from SCENEE/release-1.2.0
Release v1.2.0
2018-11-17 10:12:10 +09:00
Shin Yamamoto 281504c9c6 Fix the gesture handling
* Fix a detection of a long press gesture in content VC
* Fix a SwipeActionPanGesture is not working in the tracking scroll
    * Update DebugTableViewController to test it
2018-11-17 09:09:07 +09:00
4 changed files with 73 additions and 18 deletions
@@ -409,6 +409,15 @@ class DebugTableViewController: UIViewController, UITableViewDataSource, UITable
cell.textLabel?.text = items[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
return [
UITableViewRowAction(style: .destructive, title: "Delete", handler: { (action, path) in
self.items.remove(at: path.row)
tableView.deleteRows(at: [path], with: .automatic)
}),
]
}
}
class DetailViewController: UIViewController {
+1 -1
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "FloatingPanel"
s.version = "1.2.0"
s.version = "1.2.1"
s.summary = "FloatingPanel is a clean and easy-to-use UI component of a floating panel interface."
s.description = <<-DESC
FloatingPanel is a clean and easy-to-use UI component for a new interface introduced in Apple Maps, Shortcuts and Stocks app.
+59 -17
View File
@@ -33,7 +33,10 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate
unowned let viewcontroller: FloatingPanelController
private(set) var state: FloatingPanelPosition = .tip
private(set) var state: FloatingPanelPosition = .tip {
didSet { viewcontroller.delegate?.floatingPanelDidChangePosition(viewcontroller) }
}
private var isBottomState: Bool {
let remains = layoutAdapter.layout.supportedPositions.filter { $0.rawValue > state.rawValue }
return remains.count == 0
@@ -175,7 +178,9 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate
/* log.debug("shouldRecognizeSimultaneouslyWith", otherGestureRecognizer) */
return otherGestureRecognizer == scrollView?.panGestureRecognizer
// all gestures of the tracking scroll view should be recognized in parallel
// and handle them in self.handle(panGesture:)
return scrollView?.gestureRecognizers?.contains(otherGestureRecognizer) ?? false
}
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
@@ -183,28 +188,45 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate
/* log.debug("shouldBeRequiredToFailBy", otherGestureRecognizer) */
// Do not begin any gestures excluding the tracking scrollView's pan gesture
// until the pan gesture fails
if otherGestureRecognizer == scrollView?.panGestureRecognizer {
// The tracking scroll view's gestures should begin without waiting for the pan gesture failure.
// `scrollView.gestureRecognizers` can contains the following gestures
// * UIScrollViewDelayedTouchesBeganGestureRecognizer
// * UIScrollViewPanGestureRecognizer (scrollView.panGestureRecognizer)
// * _UIDragAutoScrollGestureRecognizer
// * _UISwipeActionPanGestureRecognizer
// * UISwipeDismissalGestureRecognizer
if let scrollView = scrollView,
let scrollGestureRecognizers = scrollView.gestureRecognizers,
scrollGestureRecognizers.contains(otherGestureRecognizer) {
return false
} else {
return true
}
// Long press gesture should begin without waiting for the pan gesture failure.
if otherGestureRecognizer is UILongPressGestureRecognizer {
return false
}
// Do not begin any other gestures until the pan gesture fails.
return true
}
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
guard gestureRecognizer == panGesture else { return false }
/* log.debug("shouldRequireFailureOf", otherGestureRecognizer) */
log.debug("shouldRequireFailureOf", otherGestureRecognizer)
// Do not begin the pan gesture until any other gestures fail except for
// the tracking scrollView's pan gesture and other gestures.
// Should begin the pan gesture without waiting for the tracking scroll view's gestures.
// `scrollView.gestureRecognizers` can contains the following gestures
// * UIScrollViewDelayedTouchesBeganGestureRecognizer
// * UIScrollViewPanGestureRecognizer (scrollView.panGestureRecognizer)
// * _UIDragAutoScrollGestureRecognizer
// * _UISwipeActionPanGestureRecognizer
// * UISwipeDismissalGestureRecognizer
if let scrollView = scrollView {
if scrollView.panGestureRecognizer == otherGestureRecognizer {
return false
}
// For short scroll contents
if scrollView.gestureRecognizers?.contains(otherGestureRecognizer) ?? false {
// On short contents scroll, `_UISwipeActionPanGestureRecognizer` blocks
// the panel's pan gesture if not returns false
if let scrollGestureRecognizers = scrollView.gestureRecognizers,
scrollGestureRecognizers.contains(otherGestureRecognizer) {
return false
}
}
@@ -215,8 +237,10 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate
is UIRotationGestureRecognizer,
is UIScreenEdgePanGestureRecognizer,
is UIPinchGestureRecognizer:
// Do not begin the pan gesture until these gestures fail
return true
default:
// Should begin the pan gesture witout waiting tap/long press gestures fail
return false
}
}
@@ -275,6 +299,11 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate
return
}
if let animator = self.animator {
animator.stopAnimation(true)
self.animator = nil
}
switch panGesture.state {
case .began:
panningBegan()
@@ -299,8 +328,22 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate
width: surfaceView.bounds.width,
height: FloatingPanelSurfaceView.topGrabberBarHeight * 2)
// When no scrollView, nothing to handle.
guard let scrollView = scrollView else { return false }
// For _UISwipeActionPanGestureRecognizer
if let scrollGestureRecognizers = scrollView.gestureRecognizers {
for gesture in scrollGestureRecognizers {
guard gesture.state == .began || gesture.state == .changed
else { continue }
if gesture != scrollView.panGestureRecognizer {
return true
}
}
}
guard
let scrollView = scrollView, // When no scrollView, nothing to handle.
state == .full, // When not .full, don't scroll.
interactionInProgress == false, // When interaction already in progress, don't scroll.
scrollView.frame.contains(point), // When point not in scrollView, don't scroll.
@@ -442,7 +485,6 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate
let targetY = layoutAdapter.positionY(for: targetPosition)
let velocityVector = (distance != 0) ? CGVector(dx: 0, dy: max(min(velocity.y/distance, 30.0), -30.0)) : .zero
let animator = behavior.interactionAnimator(self.viewcontroller, to: targetPosition, with: velocityVector)
animator.isInterruptible = false // To prevent a backdrop color's punk
animator.addAnimations { [weak self] in
guard let self = self else { return }
if self.state == targetPosition {
@@ -12,6 +12,8 @@ public protocol FloatingPanelControllerDelegate: class {
// if it returns nil, FloatingPanelController uses the default behavior
func floatingPanel(_ vc: FloatingPanelController, behaviorFor newCollection: UITraitCollection) -> FloatingPanelBehavior?
func floatingPanelDidChangePosition(_ vc: FloatingPanelController) // changed the settled position in the model layer
func floatingPanelDidMove(_ vc: FloatingPanelController) // any offset changes
// called on start of dragging (may require some time and or distance to move)
@@ -34,6 +36,7 @@ public extension FloatingPanelControllerDelegate {
func floatingPanel(_ vc: FloatingPanelController, behaviorFor newCollection: UITraitCollection) -> FloatingPanelBehavior? {
return nil
}
func floatingPanelDidChangePosition(_ vc: FloatingPanelController) {}
func floatingPanelDidMove(_ vc: FloatingPanelController) {}
func floatingPanelWillBeginDragging(_ vc: FloatingPanelController) {}
func floatingPanelDidEndDragging(_ vc: FloatingPanelController, withVelocity velocity: CGPoint, targetPosition: FloatingPanelPosition) {}
@@ -289,6 +292,7 @@ public class FloatingPanelController: UIViewController, UIScrollViewDelegate, UI
self.willMove(toParent: nil)
self.view.removeFromSuperview()
self.backdropView.removeFromSuperview()
self.removeFromParent()
completion?()
}