UICollectionView"轻扫"在iOS7应用程序管理器?

时间:2014-04-11 09:35:38

标签: uicollectionview uigesturerecognizer gestures

在任何2014+ iPhone或iPad上,双击主页按钮以查看" app manager"

enter image description here

这是一个左右的UICollectionView但它有一个"轻扫"手势..向上滑动。怎么做?移除"移除"并不容易。来自UICollectionView的单元格。


googlers的脚注..对于"剥离","撕掉",来自集合视图的一个单元格的一般问题,这里有一个完整的解释:{ {3}}希望它有所帮助。

2 个答案:

答案 0 :(得分:14)

它可能比你提问的评论简单得多。

您的单元格应该包含一个视图(您将要拖出的内容),并在该视图中添加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);
}

答案 1 :(得分:1)

我正在寻找这个功能并使用@mbehan建议我使用UICollectionView伪造了这个功能。

我做的是在收集单元格(透明背景)上添加了较小尺寸的视图,并在CollectionView上添加了单个平移手势(不在每个单元格上)然后在平移手势上移动视图,它看起来像单元格正在移动。在视图到达某个点后,我首先隐藏它,然后删除集合视图单元格。

单元格层次结构:collectionViewCell - >查看(标记值== 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,然后它应该是好的。