Leigh VDB
Leigh VDB

Reputation: 21

Swap UICollectionViewCells Positions By Long Press Gesture

Ive been having some trouble working out exactly what i am doing wrong here. My aim is to be able to drag a CollectionViewCell and have it replace the target cell with the dragged one, whilst having the replaced cell take over the position on the originally dragged cell. That even sounds confusing to me!! I can get the dragging and the cells to replace but my issue is that when i happens i get left with more and more empty Cells in the collection..

Im reasonably new to objective C so most likely im missing something stupid here.. Any help would be much appreciated. Hopefully ive included enough relevant code to help and ill link an image to show what my problem is...

Cheers Leigh

Collection View Issue Image

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self getPlayerPositions];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)getPlayerPositions
{
    SQL_PlayerTracker *pt = [[SQL_PlayerTracker alloc]init];
    playerPositionsARR = [[pt getPositions:MD]mutableCopy];
    [CV_playerPositions reloadData];
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [playerPositionsARR count];
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    OBJ_Positions *s = [playerPositionsARR objectAtIndex:indexPath.row];

    CVC_PlayerPositions *pcell = (CVC_PlayerPositions *)[collectionView dequeueReusableCellWithReuseIdentifier:@"PositionCell" forIndexPath:indexPath];
    pcell.playerName.text = s.playerName;
    pcell.positionName.text = s.position;
    pcell.playerNumber.text = [NSString stringWithFormat:@"%@",s.playerNumber];

    if (pcell.selected) {
        pcell.backgroundColor = [UIColor greenColor];
    }

    return pcell;
}

- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
    NSLog(@"MOVED INDEX %i TO %i",indexPath.row,newIndexPath.row);
    OBJ_Positions *oldPlayer = [playerPositionsARR objectAtIndex:newIndexPath.row];
    OBJ_Positions *newPlayer = [playerPositionsARR objectAtIndex:indexPath.row];

    //REMOVE TARGET POSITION FROM ARRAY
    [playerPositionsARR removeObjectAtIndex:newIndexPath.row];
    //INSERT NEW PLAYER POSITION IN TARGET POSITION
    [playerPositionsARR insertObject:newPlayer atIndex:newIndexPath.row];
    //INSERT OLD PLAYER IN MOVED PLAYERS POSITION
    [playerPositionsARR insertObject:oldPlayer atIndex:indexPath.row];
    //REMOVE ADDED POSITION OBJECT FROM INSERTION
    [playerPositionsARR removeObjectAtIndex:indexPath.row +1];
    [CV_playerPositions reloadData];
}

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    OBJ_Positions *p = [playerPositionsARR objectAtIndex:indexPath.row];
    NSLog(@"Selected Player IS %@",p.playerName);
}

#pragma mark - MOVE COLLECTION VIEW CELLS

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    return YES;
}

-(void)dragPlayer:(UILongPressGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateBegan) {
        NSLog(@"State Began");
        CGPoint point = [sender locationInView:CV_playerPositions];
        originalCellIndex = [CV_playerPositions indexPathForItemAtPoint:point];
        if (originalCellIndex) {
            UICollectionViewCell *cell = [CV_playerPositions cellForItemAtIndexPath:originalCellIndex];

        beginView =  [cell.contentView viewWithTag:cell.tag];

            beginView.backgroundColor = [UIColor greenColor];
            [beginView removeFromSuperview];

            beginView.center = [CV_playerPositions convertPoint:point toView:self.view];
            originalStartPoint = beginView.center;
            [self.view addSubview:beginView];
           [self.view bringSubviewToFront:beginView];

            OBJ_Players *pd = [playerPositionsARR objectAtIndex:originalCellIndex.row];

            NSLog(@"SELECT PLAYER NAME IS - %@",pd.playerName);
            return;
        }
    }

    if (sender.state == UIGestureRecognizerStateChanged) {
        NSLog(@"State Changed");
        if (!beginView)
            return;

        CGPoint location = [sender locationInView:self.view];
        CGPoint translation;

        translation.x = location.x - originalStartPoint.x;
        translation.y = location.y - originalStartPoint.y;
        CGAffineTransform theTransform = beginView.transform;
        theTransform.tx = translation.x;
        theTransform.ty = translation.y;
        beginView.transform = theTransform;

        return;
    }

    if (sender.state == UIGestureRecognizerStateEnded) {
        NSLog(@"STATE ENDED");

        if (beginView) {
            CGPoint epoint = [sender locationInView:CV_playerPositions];
            endCellIndex = [CV_playerPositions indexPathForItemAtPoint:epoint];
            if(endCellIndex)
            {
                OBJ_Positions *p = [playerPositionsARR objectAtIndex:endCellIndex.row];

                NSLog(@"POSITION IS - %@ AND PLAYER DRAGGED IS %@",p.position,p.playerName);
                [self moveItemAtIndexPath:originalCellIndex toIndexPath:endCellIndex];
                [beginView removeFromSuperview];

                return;

            }
        }
    }
}

- (IBAction)movingPlayer:(id)sender {
    [self dragPlayer:sender];
}

Upvotes: 2

Views: 1558

Answers (2)

Murray Sagal
Murray Sagal

Reputation: 8674

Or this one: SSCollectionViewExchangeController

Upvotes: 0

Tomer Even
Tomer Even

Reputation: 4980

i believe that this link is what you are looking for. https://github.com/lxcid/LXReorderableCollectionViewFlowLayout

it extends UICollectionViewFlowLayout to support reordering of cells. Similar to long press and pan on books in iBook.

from the github readme

Upvotes: 1

Related Questions