I am trying to get a UICollectionView
to scroll either completely vertically or completely horizontally, depending on the direction of the swipe/pan.
There should be no diagonal scrolling.
If a user swipes in a diagonal direction, it should choose the stronger direction, either vertical or horizontal, and then scroll in only that direction.
The other answers on the web are related to using a CollectionViewFlowLayout
, which allows a single direction. But, I had to subclass the UICollectionViewLayout
in order to allow both horizontal and vertical scrolling.
Now, I want to disable the diagonal scrolling, but keep the ability to horizontally/vertically scroll.
I have already used the collectionView.isDirectionLockEnabled
, but according to apple Docs:
If this property is true and the user begins dragging in one general direction (horizontally or vertically), the scroll view disables scrolling in the other direction. If the drag direction is diagonal, then scrolling will not be locked and the user can drag in any direction until the drag completes.
It still allows diagonal scrolling, hence not very helpful to my desired goal.
I am looking for some sort of override point where I could catch the direction of the drag/scroll, and then only allow a certain direction to be scrolled.
EDIT: Here is my relevant code. This code has made it harder to scroll diagonally, but on occasion, I can still get it to scroll diagonally:
var initialContentOffset: CGPoint = CGPoint.zero
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
initialContentOffset = scrollView.contentOffset
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.isDragging {
let velocity = scrollView.panGestureRecognizer.velocity(in: scrollView)
if abs(velocity.y) > abs(velocity.x) {
scrollView.contentOffset = CGPoint(x: initialContentOffset.x, y: scrollView.contentOffset.y)
} else if abs(velocity.x) > abs(velocity.y) {
scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x, y: initialContentOffset.y)
}
}
}