在任何2014年及以后的iPhone或iPad上,双击home键即可查看“应用程序管理器”
这是一个左右滚动的UICollectionView,但它具有“划走”手势..向上滑动。如何实现?从UICollectionView中“删除”单元格并不容易。
对于"剥离"、"撕裂"集合视图中一个单元格的一般问题,这里提供了一个完整而详细的解释:https://stackoverflow.com/a/24339705/294884 希望能帮到有需要的人。
在任何2014年及以后的iPhone或iPad上,双击home键即可查看“应用程序管理器”
这是一个左右滚动的UICollectionView,但它具有“划走”手势..向上滑动。如何实现?从UICollectionView中“删除”单元格并不容易。
对于"剥离"、"撕裂"集合视图中一个单元格的一般问题,这里提供了一个完整而详细的解释:https://stackoverflow.com/a/24339705/294884 希望能帮到有需要的人。
实际上,它比你的问题评论所建议的要简单得多。
您的单元格应包含一个视图(您要拖动的内容),并向该视图添加UIPanGestureRecognizer。
在手势的操作方法中,您可以将视图向上或向下移动,并且当它足够远时,您想要删除它,只需将其动画化即可。这里有很多处理此部分的问题。
这会在您的集合中留下空白,现在您需要移动东西。事实证明,这非常简单:
[_collectionView performBatchUpdates:^{
[_collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:^(BOOL finished) {
// you might want to remove the data from the data source here so the view doesn't come back to life when the collection view is reloaded.
}];
右侧移除的单元格会滑动过来,一切都很好。
另一个需要解决的问题是确保您的手势识别器和集合视图的手势识别器能够良好地协作。幸运的是,这也不太复杂。
[_collectionView.panGestureRecognizer requireGestureRecognizerToFail:pgr]; //where pgr is the recognizer you made for dragging the view off
这意味着为了让集合视图的平移手势正常工作,你的手势必须失败。因此,你要设置自己的手势只在上下平移时起作用,而让集合视图在左右平移时仍然正常工作。在你的手势识别器的代理中,实现以下方法,简单地检查你是否在 x 轴或 y 轴上移动更多。
-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint translation =[gestureRecognizer translationInView:self.view];
return(translation.x * translation.x > translation.y * translation.y);
}
masksToBounds
设置为YES
。当我实现一个集合视图并需要将项目从cv拖到另一个视图上方时,我自己也这样做了。值得注意的是,如果需要,您可以从performBatchUpdates:completion:
中进行动画处理。 - greymouser我正在寻找这个功能,并使用@mbehan的建议,我使用了UICollectionView来模拟这个功能。
我的做法是在集合视图单元格上添加一个较小尺寸的视图(透明背景),并在CollectionView上添加一个单一的平移手势(不是在每个单元格上),然后在平移手势上移动视图,看起来像单元格在移动。当视图到达某个点时,我首先隐藏它,然后删除集合视图单元格。
单元格层次结构:collectionViewCell -> View(标签值==2) -> UILabel(标签值==1) 标签只用于占位符目的。
我在下面发布我的代码:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = (UICollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"Cards" forIndexPath:indexPath];
UILabel *lblNumber = (UILabel*)[cell.contentView viewWithTag:1];
UIView *viewTouch = (UIView*)[cell.contentView viewWithTag:2];
[viewTouch setHidden:NO];
[lblNumber setText:arrCards[indexPath.row]];
return cell;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 50, 0, 30);
}
-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
{
if([gestureRecognizer isEqual:panGesture]) {
CGPoint point = [(UIPanGestureRecognizer*)gestureRecognizer translationInView:collectionView_];
if(point.x != 0) { //adjust this condition if you want some leniency on the X axis
//The translation was on the X axis, i.e. right/left,
//so this gesture recognizer shouldn't do anything about it
return NO;
}
}
return YES;
}
- (IBAction)panGestureCalled:(UIPanGestureRecognizer *)sender {
yFromCenter = [sender translationInView:collectionView_].y; //%%% positive for up, negative for down
UIView *view = sender.view;
CGPoint location = [view.superview convertPoint:view.center toView:collectionView_];
NSIndexPath *indexPath = [collectionView_ indexPathForItemAtPoint:location];
UICollectionViewCell *cell = [collectionView_ cellForItemAtIndexPath:indexPath];
UIView *touchView = (UIView*)[cell.contentView viewWithTag:2];
switch (sender.state) {
case UIGestureRecognizerStateBegan:{
originalPoint = touchView.center;
break;
};
case UIGestureRecognizerStateChanged:{
touchView.center = CGPointMake(originalPoint.x , originalPoint.y + yFromCenter);
break;
};
//%%% let go of the card
case UIGestureRecognizerStateEnded: {
CGFloat velocityY = (0.2*[(UIPanGestureRecognizer*)sender velocityInView:collectionView_].y);
if (velocityY < -30 && yFromCenter<0) {
[self hideView:touchView withDuration:0.2 andIndexPath:indexPath];
}else if ((yFromCenter< 0 && yFromCenter > -200) || yFromCenter > 0){
CGFloat animationDuration = (ABS(velocityY)*.0002)+.2;
[self resettleViewToOriginalPosition:touchView andDuration:animationDuration];
}else
[self hideView:touchView withDuration:0.2 andIndexPath:indexPath];
};
break;
case UIGestureRecognizerStatePossible:break;
case UIGestureRecognizerStateCancelled:break;
case UIGestureRecognizerStateFailed:break;
}
}
-(void)resettleViewToOriginalPosition:(UIView*)view andDuration:(float)duration{
[UIView animateWithDuration:duration
delay:0.0f
options: UIViewAnimationOptionCurveEaseOut
animations:^
{
[view setCenter:originalPoint];
}
completion:^(BOOL finished)
{
}];
}
- (void)hideView:(UIView*)view withDuration:(float)duration andIndexPath:(NSIndexPath*)indexPath
{
[UIView animateWithDuration:duration
delay:0.0f
options: UIViewAnimationOptionCurveEaseOut
animations:^
{
CGRect frame = view.frame;
frame.origin.y = -300;
view.frame = frame;
}
completion:^(BOOL finished)
{
[view setHidden:YES];
CGRect frame = view.frame;
frame.origin.y = 39;
view.frame = frame;
NSLog(@"View is hidden.");
[arrCards removeObjectAtIndex:indexPath.row];
[collectionView_ performBatchUpdates:^{
[collectionView_ deleteItemsAtIndexPaths:@[indexPath]];
} completion:^(BOOL finished) {
// you might want to remove the data from the data source here so the view doesn't come back to life when the collection view is reloaded.
}];
}];
}
将CollectionView的pagingEnabled属性设置为NO,然后就可以了。