Scaling UICollectionView with custom layout but focusing on a pinch

I am working on creating a large grid with UICollectionView

and I want it to be scalable (in total UICollectionView

, not just one cell) with a standard fixed zoom gesture. The grid in question has a custom UICollectionViewLayout

one because I needed to scroll it both horizontally and vertically.

I got a layout working fine with this SO answer , so I had a grid that you could move around. The short version is that each row of cells are section

views, and all cells are arranged based on a uniform cellSize

of (to begin with) 50.

I then developed a pinch to zoom function using a modified version of this SO answer where I basically change the layout value cellSize

when a pinch is received and then the layout is invalidated, so it re-draws with a slightly larger or smaller layout. Thus, all the cells become larger or smaller, and we zoom in.

Here's the code for the pinch gesture method:

-(void)didReceivePinchGesture:(UIPinchGestureRecognizer*)gesture {
    double newCellSize = [(IMMapViewLayout *)_mainCollectionView.collectionViewLayout cellSize] * gesture.scale;
    newCellSize = MIN(newCellSize, 100);
    newCellSize = MAX(newCellSize, 15);

    [(IMMapViewLayout *)_mainCollectionView.collectionViewLayout setCellSize:newCellSize];
    [_mainCollectionView.collectionViewLayout invalidateLayout];
}

      

And everything worked (almost) perfectly.

My problem is this: It scales from the top left corner, not from where the pinch is located. I make sense, I suppose, since we're redrawing everything, and it's all a little more, but this is clearly not the desired effect.

My first thought was to just locate the cell directly below the pinch and then use it scrollToItemAtIndexPath:atScrollPosition:animated:

to return to that cell immediately, but it doesn't seem to work and the animation becomes super choppy. Also, if you're trying to pinch anywhere other than the center of the screen, it would be difficult to move it back to that exact spot while zooming.

Here's what I have:

-(void)didReceivePinchGesture:(UIPinchGestureRecognizer*)gesture {
    double newCellSize = [(IMMapViewLayout *)_mainCollectionView.collectionViewLayout cellSize] * gesture.scale;
    newCellSize = MIN(newCellSize, 100);
    newCellSize = MAX(newCellSize, 15);

    [(IMMapViewLayout *)_mainCollectionView.collectionViewLayout setCellSize:newCellSize];
    [_mainCollectionView.collectionViewLayout invalidateLayout];

    if([gesture numberOfTouches] >= 2) {
        CGPoint touch1 = [gesture locationOfTouch:0 inView:_mainCollectionView];
        CGPoint touch2 = [gesture locationOfTouch:1 inView:_mainCollectionView];
        CGPoint mid;
        mid.x = ((touch2.x - touch1.x) / 2) + touch1.x;
        mid.y = ((touch2.y - touch1.y) / 2) + touch1.y;

        NSIndexPath *currentIndexPath = [_mainCollectionView indexPathForItemAtPoint:mid];
        [_mainCollectionView scrollToItemAtIndexPath:currentIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
    }
}

      

Can anyone help me do this scaling UICollectionView

in general, but focusing on the pinch position?

+3


source to share





All Articles