3

I want to scale (shrink) profile picture based upon scroll. But, the main thing is that, I want to scale it not from center point but from the bottom right angle. Means, that the bottom right angle should be fixed and image should be shrink from left and top edge as shown in image:

—————————————————
|               |
|    ———————————-    
|    |          |
|    |          |
|    |     —————|
|    |     |    |
|    |     |    |
—————————————————

Here is what I doing. Profile picture is named imgVwProfilePic:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offset = scrollView.contentOffset.y;
    CATransform3D avatarTransform = CATransform3DIdentity; 
    CATransform3D headerTransform = CATransform3DIdentity;

    viewHeader.alpha = 1.0;

    // PULL DOWN -----------------

    if(offset < 0)
    {
        CGFloat headerScaleFactor = -(offset) / CGRectGetHeight(viewHeader.bounds);
        int headerSizevariation = ((CGRectGetHeight(viewHeader.bounds) * (1.0 + headerScaleFactor)) - CGRectGetHeight(viewHeader.bounds))/2.0;
        headerTransform = CATransform3DTranslate(headerTransform, 0, headerSizevariation, 0);
        headerTransform = CATransform3DScale(headerTransform, 1.0 + headerScaleFactor, 1.0 + headerScaleFactor, 0);

        viewHeader.layer.transform = headerTransform;
    }

    // SCROLL UP/DOWN ------------

    else
    {
        CGFloat offset_HeaderStop = viewHeader.frame.size.height;
        headerTransform = CATransform3DTranslate(headerTransform, 0, MAX(-offset_HeaderStop, -offset), 0);

        float avatarScaleFactor = (MIN(offset_HeaderStop, offset)) / CGRectGetHeight(imgVwProfilePic.bounds) / 3.8; //1.4// Slow down the animation
        float avatarSizeVariation = ((CGRectGetHeight(imgVwProfilePic.bounds) * (1.0 + avatarScaleFactor)) - CGRectGetHeight(imgVwProfilePic.bounds)) / 2.0;

        avatarTransform = CATransform3DTranslate(avatarTransform, 0, avatarSizeVariation, 0);
        avatarTransform = CATransform3DScale(avatarTransform, 1.0 - avatarScaleFactor, 1.0 - avatarScaleFactor, 0);

        if(offset <= offset_HeaderStop){
            if(imgVwProfilePic.layer.zPosition < viewHeader.layer.zPosition){
                viewHeader.layer.zPosition = 0;
            }
        }

        else {
            if (imgVwProfilePic.layer.zPosition >= viewHeader.layer.zPosition){
                viewHeader.layer.zPosition = 2;
            }
        }
    }

    // Apply Transformations
    viewHeader.layer.transform = headerTransform;
    imgVwProfilePic.layer.transform = avatarTransform;
}

Now, I came t know that I will have to set anchor point for that image view. But I have no idea where I will set it. I set it in viewDidLoad, but it changes the original frame of that image view.

- (void)viewDidLoad 
{
    imgVwProfilePic.layer.anchorPoint = CGPointMake(1, 1); // 1,1 for bottom right corner...
}
halfer
  • 19,824
  • 17
  • 99
  • 186
NSPratik
  • 4,714
  • 7
  • 51
  • 81

1 Answers1

1

You are right that you have to set the anchor position (with IIRC is a pair of scalars in the range [0.0,1.0] for the relative-X and relative-Y position of the center).

After that, the "position" attribute of the layer (and, by extension, the origin of the view) will be w.r.t. that anchor position so you'll have to re-adjust the frames. You might try overriding

- (void) setFrame:(CGRect)frame {
    CGPoint center = CGPointMake ( frame.origin.x+0.5*frame.size.width , frame.origin.y+0.5*frame.size.height ) ;
    viewHeader.layer.position = center ;
    CGRect bounds = CGRectMake ( 0,0 , frame.size.width,frame.size.height ) ;
    viewHeader.layer.bounds = bounds ;
}

And having it take care of that.

iAdjunct
  • 2,739
  • 1
  • 18
  • 27
  • 1
    but where I will call `setFrame` method ? – NSPratik Jun 16 '15 at 14:25
  • `imgVwProfilePic.layer.anchorPoint = CGPointMake(1, 1); imgVwProfilePic.layer.transform = avatarTransform; [imgVwProfilePic setFrame:imgVwProfilePic.frame];` – NSPratik Jun 16 '15 at 14:28
  • An anchor of (1,1) is a corner. You want an anchor or (0.5,0.5) (half-way horizontally; half-way vertically) – iAdjunct Jun 17 '15 at 01:41
  • Specifically, (1,1) is the top-right corner unless you tell the layer to flip-geometry (which is set by default I think on all UIViews' backing layers) – iAdjunct Jun 17 '15 at 01:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80724/discussion-between-pratik-and-iadjunct). – NSPratik Jun 17 '15 at 04:12