2

I'd like to implement a "zoom" effect on a paging UIScrollView that I've created, but I am having a lot of difficulty. My goal is that as a user begins to scroll to the next page, the current page zooms out to become a little bit smaller. As the next page comes into view, it zooms in until it becomes its full size. The closest thing I could find to an example was this...

https://www.pinterest.com/pin/147141112804210631/

Can anyone give me some pointers on how to accomplish this? I've been banging my head against a wall for the last 3 days on this.

Machavity
  • 30,841
  • 27
  • 92
  • 100
Shadowman
  • 11,150
  • 19
  • 100
  • 198
  • Posted an answer below that should do what you want it to - let me know if you run into any problems! – trdavidson Apr 19 '16 at 20:28
  • @shadowman, I posted a slightly different answer that should give you the flexibility and control you need. – barndog Apr 21 '16 at 16:54

5 Answers5

1

Use this Code scrollview its zoom in when scroll next page, the code is given below,

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{


    GridCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CollectCell" forIndexPath:indexPath];
    cell.myscrollview.minimumZoomScale = 5.0;
    cell.myscrollview.zoomScale = 5.0;
    cell.myscrollview.contentSize = cell.contentView.bounds.size;
    return cell;
}

if you change the zoom scale value its automatically zoom in or zoom out to be showed when scroll next or previous page.

hope its helpful.

Iyyappan Ravi
  • 3,205
  • 2
  • 16
  • 30
1

I would recommend using the scrollView.contentOffset.y of your paginated UIScrollView to keep track of the scroll and to use that value to animate the transform of your views inside the UIScrollView.

So add your paginated scrollview and make self as delegate.

    paginatedScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, [[self view] bounds].size.width, [[self view] bounds].size.height-paginatedScrollViewYOffset)];
    [self.view addSubview:paginatedScrollView];

    paginatedScrollView.pagingEnabled = YES;
    [paginatedScrollView setShowsVerticalScrollIndicator:NO];
    [paginatedScrollView setShowsHorizontalScrollIndicator:NO];
    [paginatedScrollView setAlwaysBounceHorizontal:NO];
    [paginatedScrollView setAlwaysBounceVertical:YES];
    paginatedScrollView.backgroundColor = [UIColor clearColor];

    paginatedScrollView.contentSize = CGSizeMake([[self view] bounds].size.width, [[self view] bounds].size.height*2); //this must be the appropriate size depending of the number of pages you want to scroll

    paginatedScrollView.delegate = self;

Then use the delegate method scrollViewDidScroll to keep track of the scrollView.contentOffset.y

- (void) scrollViewDidScroll:(UIScrollView *)scrollView {

    NSLog(@"Scroll Content Offset Y: %f",scrollView.contentOffset.y);
    //use here scrollView.contentOffset.y as multiplier with view.transform = CGAffineTransformMakeScale(0,0) or with view.frame to animate the zoom effect

  }
Pau Senabre
  • 4,155
  • 2
  • 27
  • 36
  • Makes sense. So, in scrollViewDid scroll, that is where I would put the code to perform the gradual resize? – Shadowman Apr 18 '16 at 12:40
  • Yes, and you can trigger the zoom effect animation to different subviews by knowing in which page they are located with the following line -int indexOfPage = scrollView.contentOffset.y / scrollView.frame.size.height; – Pau Senabre Apr 18 '16 at 12:51
1

I actually just posted an answer to a very similar question, where somebody tried to achieve this effect using a UICollectionView. The link to my answer is here: https://stackoverflow.com/a/36710965/3723434

Relevant piece of code I will post here:

So another approach would be to to set a CGAffineTransformMakeScale( , ) in the UIScrollViewDidScroll where you dynamically update the pages' size based on their distance from the center of the screen.

For every page, calculate the distance of its center to the center of yourScrollView

The center of yourScrollView can be found using this nifty method: CGPoint point = [self.view convertPoint:yourScrollView.center toView:*yourScrollView];

Now set up a rule, that if the page's center is further than x away, the size of the page is for example the 'normal size', call it 1. and the closer it gets to the center, the closer it gets to twice the normal size, 2.

then you can use the following if/else idea:

 if (distance > x) {
        page.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
 } else if (distance <= x) {

        float scale = MIN(distance/x) * 2.0f;
        page.transform = CGAffineTransformMakeScale(scale, scale);
 }

What happens is that the page's size will exactly follow your touch. Let me know if you have any more questions as I'm writing most of this out of the top of my head).

Community
  • 1
  • 1
trdavidson
  • 1,051
  • 12
  • 25
0

I've done some work on stylized app guide page before.

For Me, I would use CADisplayLink to track the contentOffset.x of the scrollView, associate the value with your animation process. Don't put your views on the scrollView, put them on an overlay view of this scrollView.

This solution follows the philosophy: Fake it before you make it.

Based on CADisplayLink and physics simulation of UIScrollView, you will get smooth animation. Believe me.

duan
  • 8,515
  • 3
  • 48
  • 70
0

What you really want isn't a UIScrollView, it's a UICollectionView with a custom layout. UICollectionViewLayoutAttributes has a transform property that you can set.

Say for example, in layoutAttributesForElementsInRect::

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    guard let attributes = super.layoutAttributesForElementsInRect(rect) else {
        return nil
    }
    return attributes.map { attribute -> UICollectionViewLayoutAttributes in
        if attribute.frame.origin.y < 0 {
            let scale = -attribute.frame.origin.y / attribute.frame.height
            attribute.transform = CGAffineTransformMakeScale(scale, scale)
        }
        return attribute
    }
}

Here, you're filtering by if the element is on the screen (so non-visible elements won't be counted) and checking to see if the y offset is less than 0. If it is, you take the difference between the negated y value and the item's height and turn that into a proportional scale.

You can do it however you want, if you want the scale to be between 1 and 0.5 for example. I like this way of doing things over mucking around with a scroll view.

barndog
  • 6,975
  • 8
  • 53
  • 105