我目前正在尝试使用UICollectionView实现UITableView重新排序行为。UICollectionView有效拖放
让我们把一个的UITableView电视和UICollectionView CV(澄清以下说明)
我基本上是试图重现电视的拖&下降,但我不使用编辑模式,只要长按手势被触发,单元就准备好被移动。它工作正常,我使用CV的移动方法,一切都很好。
我更新CV的contentOffset属性以处理用户拖动单元格时的滚动。当用户转到顶部和底部的特定矩形时,我会更新contentOffset和CV滚动条。问题是当用户停止移动它的手指时,手势不会发送任何更新,这使得滚动停止并且一旦用户移动他的手指就再次开始。
这种行为是绝对不自然的,我宁愿继续滚动,直到用户释放CV,因为它是在电视中的情况。电视拖动&下降的经验是真棒,我真的想重现相同的感觉。有人知道他们在重新排序期间如何管理电视中的滚动吗?
- 我试着用一个定时器重复触发一个滚动操作,只要手势位置在正确的位置,滚动非常糟糕,并且效率不高(非常缓慢且很有跳跃性)。
- 我也尝试使用GCD在另一个线程中聆听手势位置,但结果甚至更糟。
我跑出了关于这个的想法,所以如果有人有答案,我会嫁给他!
这里是长按方法的实现:
- (void)handleLongPress:(UILongPressGestureRecognizer *)sender
{
ReorganizableCVCLayout *layout = (ReorganizableCVCLayout *)self.collectionView.collectionViewLayout;
CGPoint gesturePosition = [sender locationInView:self.collectionView];
NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:gesturePosition];
if (sender.state == UIGestureRecognizerStateBegan)
{
layout.selectedItem = selectedIndexPath;
layout.gesturePoint = gesturePosition; // Setting gesturePoint invalidate layout
}
else if (sender.state == UIGestureRecognizerStateChanged)
{
layout.gesturePoint = gesturePosition; // Setting gesturePoint invalidate layout
[self swapCellAtPoint:gesturePosition];
[self manageScrollWithReferencePoint:gesturePosition];
}
else
{
[self.collectionView performBatchUpdates:^
{
layout.selectedItem = nil;
layout.gesturePoint = CGPointZero; // Setting gesturePoint invalidate layout
} completion:^(BOOL completion){[self.collectionView reloadData];}];
}
}
为了使CV滚动,我使用的方法:
- (void)manageScrollWithReferencePoint:(CGPoint)gesturePoint
{
ReorganizableCVCLayout *layout = (ReorganizableCVCLayout *)self.collectionView.collectionViewLayout;
CGFloat topScrollLimit = self.collectionView.contentOffset.y+layout.itemSize.height/2+SCROLL_BORDER;
CGFloat bottomScrollLimit = self.collectionView.contentOffset.y+self.collectionView.frame.size.height-layout.itemSize.height/2-SCROLL_BORDER;
CGPoint contentOffset = self.collectionView.contentOffset;
if (gesturePoint.y < topScrollLimit && gesturePoint.y - layout.itemSize.height/2 - SCROLL_BORDER > 0)
contentOffset.y -= SCROLL_STEP;
else if (gesturePoint.y > bottomScrollLimit &&
gesturePoint.y + layout.itemSize.height/2 + SCROLL_BORDER < self.collectionView.contentSize.height)
contentOffset.y += SCROLL_STEP;
[self.collectionView setContentOffset:contentOffset];
}
发布答案:
来源。总结帖子的内容将大大改善这个答案。 – David
谢谢你的回答,那就是我正在寻找的。他用计时器管理卷轴,但他以我更聪明的方式进行。它给了我一个计时器可以实现的技巧的证明,我将再次看看该解决方案,再次感谢。该代码很安静,并且不尊重Apple的CVC标准,但他的滚动解决方案很有趣。谢谢! – foOg
非常简单,谢谢。唯一的一点是,在拖拽项目时,其背景会变黑。其原始背景清晰(透明)。 将尝试修复它,并报告回来。 – ancajic