10

I started studying objective-c using the iPhone and iPad apps for Absolute Beginners by Rory Lewis book but i got stuck on the 5th chapter.

I want to make a button that shrinks an image.
My problem is, that after I wrote all the code, the image shrinks to the point (0, 0) of the UIImageView (the top left), while in the video the image shrinks to its center. I've done some research and found out that CGAffineTransform uses the center of the object to make translations, rotations etc.

So why does it not work in my case?

I have the latest Xcode version and haven't done anything strange. I hope I've been clear. Sorry for my English.

EDIT Sorry for the code, but i wrote the question from my phone. Anyway the incriminated part goes something like this

- (IBAction)shrink:(id)sender {

if(hasShrink == NO){
    [shrinkButton setTitle:@"Grow" forState:UIControlStateNormal];
}
else if(hasShrink == YES){
    [shrinkButton setTitle:@"Shrink" forState:UIControlStateNormal];
}
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:1.0];
        myIcon.transform = CGAffineTransformMakeScale(.25, .25);
        hasShrink = YES;
        [UIView commitAnimations];

}

All the animations are correctly written and the app does work, it just shrinks to the top left. Why is the point not set to the center of the UIImageView by default like it should be?

EDIT: I figured out it was a problem caused by AutoLayout. Once disabled everything went smooth ;)

halfblood17
  • 657
  • 1
  • 6
  • 21

3 Answers3

9

If you are transforming a view mangled managed by auto-layout, you may experience some strange side-effects. See this answer for more details.

The solution I ended up employing was to encapsulate the view I wanted to transform inside another view of exactly the same size. The outer view had the appropriate layout constraints applied to it while the inner view was simply centered in its container. Applying a CGAffineTransform scale transform to the inner view now centers properly.

Community
  • 1
  • 1
devios1
  • 36,899
  • 45
  • 162
  • 260
8

Old question... but just in case others come looking:

The CGAffineTransform acts (rotates, scales) around an anchorPoint.

If you are sizing to 0, 0 then your anchor point is set to 0, 0. If you want it to size to a different point, such as the center of the image, you need to change the anchor point.

The anchor is part of a layer

So if you have a UIImageView called imageview, you would make a call like this to set the anchor to the center of imageview:

[imageview.layer setAnchorPoint:CGPointMake(0.5, 0.5)];
picciano
  • 22,341
  • 9
  • 69
  • 82
HalR
  • 11,411
  • 5
  • 48
  • 80
  • 4
    `anchorPoint` is measured in relative values and defaults to `0.5, 0.5`, which is the center of the view. Using pixel values will not give you expected results. – devios1 Sep 09 '14 at 01:12
7

Try something like this:

CGAffineTransform t = CGAffineTransformMakeScale(0.5, 0.5);
CGPoint center = imageView.center; // or any point you want
[UIView animateWithDuration:0.5
                 animations:^{
                    imageView.transform = t;
                    imageView.center = center;
                 }
                 completion:^(BOOL finished) {
                    /* do something next */
                 }];

Next time show your code. It will be easier to help you.

Check this project: https://github.com/djromero/StackOverflow/archive/Q-13706255.zip

You must study how autolayout and autoresize affect your views. In the project above both are disabled to let you see how it works.

djromero
  • 19,551
  • 4
  • 71
  • 68
  • I've done as you said but if i print the value of `myImage.center.x` and `myImage.center.y` it keeps on pointing to the left upper corner. I've tried 3 times to restart the project and still have the same problem, even writing just the code for the shrink button. `- (IBAction)shrink:(id)sender { if(hasMoved == NO && hasShrink == NO){ [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:1.0]; _myIcon.transform = sizeShrink; hasShrink = YES; [UIView commitAnimations];` – halfblood17 Dec 05 '12 at 07:54
  • If you're using that code you're not doing what I said. Please, update the question with your source, don't add comments (hard to read, not the right place). – djromero Dec 05 '12 at 10:53
  • ok, I'll fix this. But still i tried to use your code only and nothing changes.. it still resizes while moving. – halfblood17 Dec 05 '12 at 11:49
  • Are you sure your imageView is moving? Maybe it has a weird content fitting. Have a look at `UIView`’s [`-contentMode`](http://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html#//apple_ref/occ/instp/UIView/contentMode) and [`-contentStretch`](http://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instp/UIView/contentStretch) properties. – Zev Eisenberg Dec 06 '12 at 00:10