6

I'm working on making a large grid using a UICollectionView, and I want it to be zoomable (the entire UICollectionView, not just a single cell) with the standard pinch-to-zoom gesture. The grid in question has a custom UICollectionViewLayout, because I needed it to scroll both horizontally and vertically.

I got the layout working perfectly with this SO answer, so I had a grid that you could move all around on. The short version is that each row of cells is a section of the view, and all the cells are positioned based on a uniform cellSize of (to start with) 50.

Then I worked out the pinch-to-zoom ability using a modified version of this SO answer, where I basically change the layout's cellSize value when the pinch gesture is received, and then invalidate the layout so it re-draws with the slightly larger or smaller layout. Thus, all the cells get bigger or smaller, and we have zooming.

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 was working (almost) perfectly.

My problem is this: it zooms from the top-left corner, not from where the pinch is located. Makes sense, I suppose, since we're redrawing everything and it's all a little bigger, but it's obviously not the desired effect.

My first thought was simply to detect the cell directly under the pinch and then use scrollToItemAtIndexPath:atScrollPosition:animated: to move back to that cell instantaneously, but it doesn't seem to be working, and the animation gets super-choppy anyway. Also, if you're pinching anywhere other than the center of the screen, it would be hard to move it right back to that exact spot repeatedly during the zoom.

Here's what I've got now:

-(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 make this UICollectionView zoom, in its entirety, but centered on the position of the pinch?

Community
  • 1
  • 1
Nerrolken
  • 1,975
  • 3
  • 24
  • 53
  • Did you ever find a solution to this problem? I've tried the last effort you posted and you're right, it is super choppy! – Scaroth Aug 11 '15 at 16:07
  • @Niall No, sadly I never did. I ended up having to put that project on hold until I can find a way to achieve what I'm aiming for some other way. :/ – Nerrolken Aug 11 '15 at 16:11
  • that's a shame. I'm also getting to the point where I might need to move on. I have misgivings about the performance as it stands. As soon as I use autolayout on a view in the cell, the zooming gets jerky. – Scaroth Aug 11 '15 at 19:08

0 Answers0