iOS7 应用管理器中的 UICollectionView “滑动”?

Posted

技术标签:

【中文标题】iOS7 应用管理器中的 UICollectionView “滑动”?【英文标题】:The UICollectionView "swipe-away" in iOS7 app manager? 【发布时间】:2014-04-11 09:35:38 【问题描述】:

在任何 2014 年以上的 iPhone 或 iPad 上,双击主页按钮以查看“应用管理器”

这是一个左右 UICollectionView 但它有一个“滑动”手势..向上滑动。它是如何完成的?从 UICollectionView 中“移除”一个单元格并不容易。


googlers 的脚注 .. 对于“剥离”、“撕掉”、集合视图中的一个单元格的一般问题,这里有一个完整的解释:https://***.com/a/24339705/294884希望它对某人有所帮助。

【问题讨论】:

在内部,这不是一个集合视图。它是一系列滚动视图,由控制器管理。事实上,我正在做类似的事情,但还没有什么要宣布的。 Ahhh ...**这是一系列滚动视图,由控制器管理** Leo 典型的令人难以置信的洞察力! :O Joe,您可以将调试器附加到模拟器上的 SpringBoard 并检查视图层次结构。 嗯 .. 这就是你说的那些听起来很容易的事情之一 :) 谢谢,尽管我会深入研究这一点!您能否将最后一条评论作为答案,因为它非常有用??? 让我看看能不能及时拿出真正的解决方案。 【参考方案1】:

这可能比您问题中的 cmets 建议的要简单得多。

您的单元格应该包含一个视图(您要拖出的东西),并且您向该视图添加一个 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: 制作动画,这毫无价值。【参考方案2】:

我一直在寻找这个功能并使用@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,然后就可以了。

【讨论】:

以上是关于iOS7 应用管理器中的 UICollectionView “滑动”?的主要内容,如果未能解决你的问题,请参考以下文章

Flickr 照片管理器中的 JSON 警告

任务管理器中的多个应用程序

Tomcat 管理器中的 Web 应用程序版本

修改任务管理器中的应用程序图标,而不是系统托盘中的应用程序图标

ios7 datepicker当前日期未突出显示

Table Cell 中的 UICollection 视图在 Swift 3 中不显示图像