How to measure velocity of Table View's scrolling? - ios

I'd like to call or not call a method depending on how fast user has scrolled.
It has to be instantly measured as user's finger goes because the method needs to be either called or ignored the second it starts moving, not when it has stopped.

This works for me.
CGPoint scrollVelocity = [[self.tableView panGestureRecognizer] velocityInView:self.tableView];
NSLog(#"scroll velocity : %f",scrollVelocity.y);

This method exposes the velocity value. It is part of the scroll view delegate.
optional func scrollViewWillEndDragging(_ scrollView: UIScrollView,
withVelocity velocity: CGPoint,
targetContentOffset: UnsafeMutablePointer<CGPoint>){
}

Related

Stop scrolling UITableView perfectly on cell

I have a list of cells of varying height, and I want the scroll to top perfectly at the top of a cell.
For this I can use
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
And I can set the targetContentOffset to the top of a cells frame.
However if cells yet to be laid out have a height different from their estimated height, then this destination cells origin will change, and I don't get a chance to account for this.
Is there anyway to land perfectly on a cell after a scroll when the origin can change?

Stop CollectionView from scrolling during interaction

I'm trying to stop a UICollectionView from scrolling if the velocity is too low.
Using the delegate method:
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
I've tried many different approaches, but nothing seems to stop the scrollview. I've tried combinations of:
scrollView.layer.removeAllAnimations()
scrollView.isScrollEnabled = false
scrollView.layoutIfNeeded()
You can just set the current contentOffset as a target offset.
targetContentOffset.pointee = scrollView.contentOffset

How to change the targetContentOffset of a UICollectionView in Swift?

In my UIViewController I have a UICollectionView. The delegate is set properly. It just works fine. isPagingEnabled is set to true. But now I want to change the paging-positions I tried it within scrollViewWillEndDragging, because in the documentation it says:
Your application can change the value of the targetContentOffset parameter to adjust where the scrollview finishes its scrolling animation.
This functions is called properly but the only thing happens when I want to set a new Endpoint, the UICollectionView scrolls to 0.
This is my code:
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
print(scrollView.contentOffset, "actual Offset")
print(targetContentOffset.pointee, "future offset")
targetContentOffset.pointee = CGPoint(x: 100, y: 0)
print(targetContentOffset.pointee, "new future offset")
}
At the print("new future offset"), it prints the right value. So it seems the value is mutated after this function.
func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint,
withScrollingVelocity velocity: CGPoint) -> CGPoint
Description:
If you want the scrolling behavior to snap to specific boundaries, you
can override this method and use it to change the point at which to
stop. For example, you might use this method to always stop scrolling
on a boundary between items, as opposed to stopping in the middle of
an item.
Override this layout method instead of directly changing value of targetContentOffset.
If you want the scrolling behavior to snap to specific boundaries, you can override this method and use it to change the point at which to stop. For example, you might use this method to always stop scrolling on a boundary between items, as opposed to stopping in the middle of an item.
Docs:
https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617729-targetcontentoffset

Disable UIScrollView inertia (scrollViewDidEndDecelerating) Swift

Setup: I have a Scroll View that works great horizontally as well as a UISwipeGestureRecognizer that triggers a segue to another view when I swipe down.
Problem: If I am scrolling horizontally and I begin to swipe down (vertical scrolling disabled) WHILE the scrolling is decelerating, the swipe down action (segue) does not execute. It only works once the scrolling deceleration is complete.
Is there a way to disable the scroll deceleration (aka inertia) so that my swipe down gesture can be detected instantly? Perhaps there's a workaround to force UISwipeGestureRecognizer to be detected first?
Solutions in Swift are highly appreciated!
UIScrollView has a pinchGestureRecognizer and a panGestureRecognizer.If you have a UISwipeGestureRecognizer,the gesture will most likely be recognized as a UIPanGestureRecognizer.
You can add a dependence to solve the problem:
scrollView.panGestureRecognizer.requireGestureRecognizerToFail(swipeGesture)
Swift 3:
To disable decelerating scroll you can try:
func scrollViewWillEndDragging (scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
targetContentOffset.memory = scrollView.contentOffset
}
or you change this value:
scrollView.decelerationRate = UIScrollViewDecelerationRateNormal
// UIScrollViewDecelerationRateFast is the other param
About your gestureRecognizer interferences you can call this method to exclude touching from:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
// insert here views to exclude from gesture
if touch.view!.isDescendantOfView(self.excludeThisView) {
return false
}
return true
}
did you look here?
Deactivate UIScrollView decelerating
the answer
-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
[scrollView setContentOffset:scrollView.contentOffset animated:YES];
}
converted to swift is
func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
scrollView.setContentOffset(scrollView.contentOffset, animated: true)
}

Slow animation of table view deceleration

Trying to set targetContentOffset in scrollview delegate method to snap tableView to desired position(top,middle,bottom),but after snap action the tableView decelerate to the position but its not finishing animation very fast it gets slow down after few seconds.i tried to change the speed by putting some lower number (0.97,0.96…..) but still its is same,I have also tried putting the same content in UIView animation block but there is no change in speed? How Can I speed up deceleration Rate more than UIScrollViewDecelerationRateFast?
tableView.decelerationRate = UIScrollViewDecelerationRateFast
var scrollRect:CGRect = scrollView.frame;
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
scrollRect.origin.y = self.getNextPosition(position, previousPosition: self.previousPosition, fastScroll: isFastScroll! , andScrollDirection: self.scrollDirection!,isFrameChanged:frameChanged)
targetContentOffset.memory.y = scrollRect.origin.y
}

Resources