rotate UIView/UITableView around a point - iphone

I try to rotate a UITableView around a point, I use this IBAction that work only for half
CALayer *l = self.table.layer;
l.anchorPoint = CGPointMake(0,0);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
CGAffineTransform rotate = CGAffineTransformMakeRotation(0.6);
table.transform = rotate;
[UIView commitAnimations];
when I click on the button firs of all the table move to another position than rotate around a corner...the problem is that the table move to another position at the beginning of animation..If I put
CALayer *l = self.table.layer;
l.anchorPoint = CGPointMake(0,0);
on viewdidload when I open application the tableview is to another position but the animation is correct, it's seems that l.anchorPoint move the table to another position...where is the error?

The problem is possibly with l.anchor.
The setAnchor method sets the centre point of frame in the layer. You have set the centre point in the top left corner (0,0). (1,1) would be the bottom right.
The layer positions itself by using the centre property. This represents the coordinates in the super layer. Because you have change the anchor point, your layer will be offset as the centre property is now being reference from the top left, but with the same sub layer coords.
If you set the anchor to (1,1) you would notice that the bottom right corner would now be where the top left corner was.
To solve your problem, set the anchor point and reposition your layer by setting centre property.
l.center = CGPoint (l.center.x - (l.frame.size.width/2), l.center.y - (l.frame.size.height/2);
The above code should do the trick.

Related

CGAffineTransform and scaling to center of the image

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 ;)
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.
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)];
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.

Simulate push view animation inside UIView

I have a single UIView with some labels that display attributes from objects inside an array. I'm using gesture recognizers to change the current element in the array and hence the text in the labels. My question is how do I mimic a push animation without actually pushing a new view controller. Thanks for your help.
Thats simple way to use CGAffineTransformMakeTranslation to move any view from X axis to Y axis using UIViewAnimation. Before using this transition set your object frame to some x,y axis(0,0) and pass your x and y to move from.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
CGAffineTransform transform = CGAffineTransformMakeTranslation(x,y);
YOUR ViewOBJECT.transform=transform;
[UIView commitAnimations];
Have you tried to use the UIView class methods for animation? For example this could help:
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations
In the animations block you could move one view out and another in.

Animate size of a UIView around center point

I have a UIView which I want to grow from it's center when a user touches it. The problem is that when animating it the view expands left and then moves to the right, whereas I want it to expand to the left and right, while keeping the center point the same.
This is the code I have at the moment:
[UIView animateWithDuration:1 animations:^(void) {
[view setFrame:CGRectMake(-10, 0, 320, view.frame.size.height)];
}];
I didn't think it was going to be difficult to do this, but it seems it is. Short of animating it manually with a timer I have no idea how to get it to expand from it's center.
I am not quite sure why it's working for you in a weird manner. Did you alter the anchorPoint property in any way? Otherwise it should grow from center.
Does doing
CGRect newFrame;
newFrame = CGRectInset(view.frame, -10, -30);
[UIView animateWithDuration:1 animations:^(void) {
view.frame = newFrame;
}];
also give you the same result? What about this?
[UIView animateWithDuration:1 animations:^(void) {
view.transform = CGAffineTransformScale(view.transform, 1.1, 1.1);
}];
Try the code given by #Deepak Danduprolu and also don't forgot to UnCheck the "Use AutoLayout" checkbox in the show file inspector window of the storyboard.
It works for me.
Just offset the X,Y position of the view. Lets say you're DECREASING both the width and height of the frame by 20 points: you should then ADD 10 points to both the X and Y position of the frame.

Opening a curtain: Animation with Core Animation

I would like to animate a curtain, which gets opened. I have two images: one for the left and one for the right side of the curtain (depicted in red). I would like to smoothly slide them away with Core Animation. For what animation type should I look for? How do I achieve a realistic sliding style?
Regards,
Stefan
alt text http://img.skitch.com/20100627-8ytxrbe64ccbruj49c2pbs7kt2.png
I'm not sure why people are suggesting using a translation. If all you need to do is slide the images, simply call -setCenter on each image view inside an animation block. Like this:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[leftCurtainImageView setCenter:pointOffScreenLeft];
[rightCurtainImageView setCenter:pointOffScreenRight];
[UIView commitAnimations];
Where pointOffScreenLeft, and pointOffScreenRight are calculated something like:
CGPoint pointOffScreenLeft = CGPointMake(
-[leftCurtainImageView bounds].size.width,
[leftCurtainImageView frame].origin.y);
CGPoint pointOffScreenRight = CGPointMake(
[rightCurtainImageView frame].origin.x +
[rightCurtainImageView bounds].size.width,
[leftCurtainImageView frame].origin.y);
These calculations assume that the curtains are positioned at the far left and far right edges respectively of their containing view.
The easiest solution would be to have to imageview or CGLayers and then use CGAffineTransformTranslate in an animation block to slide them off screen.
Man
After a long search. The only way I could find is this.
https://github.com/Ciechan/BCMeshTransformView

Convert coordinates between parent/child UIView after CGAffineTransform

Before I go into doing everything by hand I would like to ask if there is some help to get from the framework.
I have a UIView that holds another UIView with a map. The parent UIView holds some legends for the map. Initially I define some coordinates in the map view. e.g. (100, 40), and place a piece of graphics there in the parent view (like a tack in google maps etc.). The parent view and the child view are both 300x200 and have the same origin. This means that (100, 40) is the same point in both views.
Now I zoom and move the child UIView(the map) using CGAffineTransform and the coordinate (100, 40) is now situated somewhere else. The parent view is effectively a mask here.
Can I use the CGAffineTransform Matrix or another part of the framework to calculate and inform the parent view where to place the tack now that the point has moved?
i.e. (100, 400) in the child view compared to (100, 40) in the parent view, what does it compare to after the transformation?
Thank you for suggestions or help given.
The animation of the child UIView
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
CGAffineTransform transform = CGAffineTransformMakeScale(1.8f, 1.8f);
worldMap.transform = transform;
worldMap.bounds.origin = newPos;
[UIView commitAnimations];
UIView's -convertPoint:toView: and -convertPoint:fromView: should work for you.