您将如何使用此行为实施UICollectionView
?
这个想法是,一旦用户导航过某个点,他们就无法再返回并再次查看这些单元格。
我尝试解决方案一直是在集合视图上侦听手势,如果在元素上发生滑动则禁用滚动。显而易见的问题是用户可以简单地保持和拖动任何特定的单元格。
有什么想法吗?
答案 0 :(得分:1)
我认为这种行为可能会让您的用户感到困惑。
也许你应该尝试添加一些弹性/弹跳,这样你的用户就不会那么困惑了。
无论如何,我看到了两种不同的方法来实现这一点而没有子类化
1 /由于UICollectionViewDelegate符合UIScrollViewDelegate,您可以使用– scrollViewWillBeginDragging:
获取滚动视图的起始偏移量,然后在– scrollViewDidScroll:
中比较新偏移量的x值。如果新的offset.x的值小于起始值,则将其设置为0并更新滚动视图。
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
offset = scrollView.contentOffset;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint newOffset = scrollView.contentOffset;
if (newOffset.x < offset.x) {
// scrolling to the left, reset offset
[scrollView setContentOffset:offset];
}
}
由于iOS中存在滚动惯性,scrollViewDidScroll:
会被调用很多时间,因此可能会导致性能问题。您可以通过使用UIScrollViewDelegate中的scrollViewWillEndDragging:withVelocity:targetContentOffset:
定位偏移量来减少调用次数。
2 /或者你可以使用我刚刚谈到的方法scrollViewWillEndDragging:withVelocity:targetContentOffset:
,它用动画将偏移量设置回它的开头。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
CGPoint newOffset = scrollView.contentOffset;
if (newOffset.x < offset.x) {
// scrolling to the left, reset offset with animation
targetContentOffset->x = offset.x;
}
}
3 /你谈到UISwipeGestureRecognizer
,你试过UIPanGestureRecognizer
吗?这就是“简单的保持和拖动”。
答案 1 :(得分:0)
您可以像实现无限滚动视图一样实现它,方法是根据滚动偏移量添加/删除项目。
viewDidScroll:
方法(UICollectionViewDelegate
)这个简单的实现可能会导致动画不稳定,一旦它正常工作,您可能需要进行一些优化,但这应该可以帮助您开始。
答案 2 :(得分:0)
另一种可能的解决方案是在你向左滚动时,不断地“重新定位”所有元素以显示它们在滚动之前的位置。
您可以通过跟踪遇到的最高偏移X来实现此目的,并在当前偏移量X低于最大值时重新定位您的单元格。这样你就会觉得你的单元格没有移动或你无法滚动,但实际上你会滚动。
答案 3 :(得分:0)
在我的情况下,我有一个分页集合视图,所以我必须在集合视图的最后一项减速时以及每页的自动减速时小心。
要解决此问题,我只是在集合视图“自动移动”时禁用用户交互。
这里是代码:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!_isDragging) // <-- only do things if the user is dragging!
return;
CGPoint contentOffset = scrollView.contentOffset;
// If we move to the left
if (contentOffset.x < _contentOffset.x)
{
CGSize contentSize = scrollView.contentSize;
// If content offset is moving inside contentSize:
if ((contentOffset.x + scrollView.bounds.size.width) < contentSize.width)
scrollView.contentOffset= _contentOffset;
}
else
{
// Update the current content offset
_contentOffset = contentOffset;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
_isDragging = YES;
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
_isDragging = NO;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (decelerate)
{
// If willDecelerate, stop user interaction!
_collectionView.userInteractionEnabled = NO;
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// Once deceleration is finished, enbale user interaction
_collectionView.userInteractionEnabled = YES;
// Set the new content offset
_contentOffset = scrollView.contentOffset;
}