Pergunta

Em qualquer iPhone ou iPad 2014+, clique duas vezes no botão home para ver o "gerenciador de aplicativos"

enter image description here

Este é um UICollectionView esquerdo-direito, MAS tem um gesto de "deslizar".deslize para cima.Como isso é feito?Não é tão fácil “remover” uma célula de um UICollectionView.


Nota de rodapé para googlers.para o problema geral de "descascar", "arrancar", uma célula de uma visualização de coleção, aqui está uma explicação completa e organizada: https://stackoverflow.com/a/24339705/294884 Espero que ajude alguém.

Foi útil?

Solução

Pode ser muito mais simples do que os comentários da sua pergunta sugerem.

Sua célula deve conter uma visualização (aquilo que você vai arrastar) e você adiciona um UIPanGestureRecognizer a essa visualização.

No método de ação do gesto, você move a visualização para cima ou para baixo e, quando ela fica distante o suficiente para que você queira excluí-la, basta animá-la.Há muitas perguntas aqui relacionadas a esta parte.

Isso deixa uma lacuna em sua coleção e agora você precisa movimentar as coisas.Acontece que isso é bastante simples:

[_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.
}];

O material à direita da célula removida desliza e estamos todos bem.

Outro problema a ser superado:certificando-se de que seu reconhecedor de gestos e a visualização da coleção funcionem bem juntos.Felizmente, isso também não é muito complicado.

[_collectionView.panGestureRecognizer requireGestureRecognizerToFail:pgr]; //where pgr is the recognizer you made for dragging the view off

Isso significa que para que o gesto panorâmico da visualização da coleção funcione, o seu deve falhar.Então você vai querer configurar o seu para que ele só funcione ao mover para cima e para baixo, e deixar a visualização da coleção ainda funcionar para movimentos panorâmicos da esquerda para a direita.No delegado do seu reconhecedor de gestos, implemente o método a seguir, que simplesmente verifica se você está se movendo mais no eixo x ou no eixo y.

-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
{
    CGPoint translation =[gestureRecognizer translationInView:self.view];

    return(translation.x * translation.x > translation.y * translation.y);
}

Outras dicas

Eu estava procurando por essa funcionalidade e usando a sugestão do @mbehan, falsifiquei essa funcionalidade usando UICollectionView.

O que fiz foi adicionar uma visualização de tamanho menor em uma célula de coleção (fundo transparente) e adicionar um único gesto panorâmico em CollectionView (não em cada célula). Em seguida, no gesto panorâmico, movo a visualização e parece que a célula está se movendo.Depois que a visualização atinge algum ponto, primeiro a escondo e, em seguida, excluo a célula da visualização da coleção.

Hierarquia celular:CollectionViewCell -> View (Tag Value == 2) -> Uilabel (Tag Value == 1) O rótulo é usado apenas para fins de espaço reservado.

estou postando meu código abaixo:

- (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.
     }];
 }];
}

e mantenha pagingEnabled de CollectionView como NO e então estará pronto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top