I do not understand why/how CGAffineTransformTranslate works - iphone

I am creating a view and having it move on to the screen from left to right. I had a hard time getting it to work the way I wanted but when I did I was baffled at the way it worked.
I thought I would have to create the view off screen to the left then use CGAffineTransformTranslate to move it onto the screen. But instead I am creating it on the screen, but it still works great. I am a bit confused.
Here I am creating the view...
profileViewControllerForIPad = [[ProfileViewController alloc] initWithFrame:CGRectMake(0, 0, 512, 446)];
As you can see the origin is 0,0. So on screen, right?
Here is the thransform...
[UIView animateWithDuration:0.5
animations:^{
self.view.transform = CGAffineTransformTranslate(CGAffineTransformIdentity,self.view.frame.size.width, 0.0);
}
];
As you can see I am setting the tx value to the width of the CGAffineTransformTranslate which I thought was the value for the number of pixels you wanted it to move from it's current position, origin.x of 0, which I expected would move it to the middle of the screen somewhere. Instead, it slides right in with it's new origin.x right at 0 where I want it.
BTW CGAffineTransformIdentity works great sliding the view right back off the screen.
Can someone explain this to me. The docs seem to say something different.
Thanks,
John

I think I understand it now. I think it depends on when you execute CGAffineTransformTranslate.
If you are creating the object and call CGAffineTransformTranslate before you add it to it's superview, when you add it to it's superview it will display at a position that will allow it to move to it's defined position the amount and direction defined in the CGAffineTransformTranslate call.
If on the other hand the object you want to move is already being displayed, the object will be moved from it's current position to the new position.
In my case where I was creating a new UIView and wanted it to slide in from the left side of the screen, if I called CGAffineTransformTranslate at the same time that I created and added the view, I would have to define the view's frame at it's final on screen location.
Alternatively one could call CGAffineTransformTranslate in a timer method. In this case you would define the view's frame off screen, add it to the display and create the timer. The timer method would then move it on screen with CGAffineTransformTranslate.

I think you can animate the frame property (- animateWithDuration:animations:) of your viewControllers -view instead of using a transform, which is much easier to use and understand.

Related

How to make a method that rotates a UIView work many times

I have a view that slides up from the bottom of the screen when the user swipes up and when this happen a little arrow is supposed to rotate so that it is now pointing downwards. In a similar fashion, when the view is slid away to the bottom of the screen, the arrow should rotate again so that it points upwards. Ideally, I would like to call the same method every time the view slides in or out to rotate the arrow 180 degrees. Right now I am using:
[UIView animateWithDuration:.5 animations:^{
viewToBeRotated.transform = CGAffineTransformMakeRotation(M_PI);
}];
This works fine the first time but then doesn't do anything on further method calls, any pointers on how to do do this correctly?
When you set a transform on a view you erase previous transform.
To have multiple transforms applied to one view at the same time you must "add" them. Each CGAffineTransformMake{Rotation/Scale/etc} has an equivalent which allows you to "add" a transform to another one.
To resolve your issue you can use the following :
self.iv.transform = CGAffineTransformRotate(self.iv.transform, M_PI);

Animate UIView grow/shrink

I have a UILabel I want to animate growing and shrinking. While the size changes I need the bottom left corner to remain static so that it always appears directly above a bottom toolbar. I am using the following code to make the label grow:
[UIView animateWithDuration:kAnimationDuration delay:0.0 options:UIViewAnimationCurveEaseInOut
animations:^{
CGFloat lblHeight = 42.0f;
[label setFrame:CGRectMake(0.0,
CGRectGetMaxY(self.view.bounds) - kBottomBarHeight - lblHeight,
CGRectGetMaxX(self.view.bounds),
lblHeight)];
} completion:^(BOOL finished) { }];
and to make it shrink I use the same logic except that lblHeight is set to 17.0f
The view correctly grows but when I try to shrink it the frame change animation is not animated. It blips into the new size and then animates into the new origin/location. I need the frame change to be animated. Can anyone see what I'm doing wrong?
After some tinkering I've managed to get the desired behavior by doing the following.
In the expand method, I use the UIView animation to alter the frame.
In the shrink method, I use the UIView animation to alter the bounds and center.
I'm a little baffled as to why this works but trying to shrink with the frame does not. If anyone can share some insight into this that would be great.
You should not really use frames to animate, rather you should use the transform property of your label.
However, since you want one corner to remain static, I think its best you use Core Animation. CALayer has a property called anchorPoint that determines which point a layer will rotate with respect to, and I'm pretty sure it is also valid for grow/shrink effects.

How to implement flip transition effect for UIView

How to implement flip transition effect for UIView as like in "flipboard" application. here i already have sample which will make flip from left to right or right to left. But here i want to implement fold flip from bottom to top or top to bottom.
you can use the below line of codes for this kind of animations
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5];
[UIView transitionFromView:view2 toView:view1 duration:3 options:UIViewAnimationOptionTransitionFlipFromBottom completion:NULL];
[UIView commitAnimations];
u can set the duration and animation transition as per the requirement.. was working only in ios5..
check this tutorial: http://www.gethugames.in/blog/2012/02/extended-epgltransitionview.html
and this project: https://github.com/saiy2k/EPGLTransitionView
PS: Its my own blog and link to my fork of EPGLTransitionView
Here's a concept of how I would try to approach the problem. Maybe I'll try to implement it in free time to have a sample handy.
The moment you start the animation, make a snapshot of current UIView by reading its graphics context into a bitmap
Create three (yeah, three -- bear with me_) UIViews with sizes so that they make up for two halves of the view to be flipped, with two views for area of the right half
Draw half of the bitmap on the left view (first one), right half on the right view (second one), in their respective drawRect: implementations
Hide the original view
Create the next view we want to transition to
get its contents into a bitmap as well
hide the next view
make the third temporary UIView to draw the right half of the image (third one)
position the third one under the second one
Animate half of the flip of the second one along its left edge
make the second one display left half of the next view
Make the rest of the flip animation
After having done the transition, show the next view, hide all temporary views
Et voilla! At least I hope.
I think that instead of those three UIViews you could use one UIView with three CALayers instead.
And there's an issue of doing the transition interactively, with the user sliding his finger over the pages.
I also I think there's an issue of the flipping view to have a two-sided layer. Haven't had the opportunity to play with those properties and what they can help to achieve.
Another solution would be to create a texture from UIView's contents and put up an OpenGL surface over it (alpha-transparent CAEAGLLayer-based one of course). Then what you'll do with the triangles that are textured with that image is only limited by your imagination. I guess that would also allow to create a Genie-like move-to-trash animation that Mail iOS app uses.
Edit: Oh, sorry, I was thinking of a right-to-left flipboard-style flip, not top-to-bottom, but overall idea is the same of course.

Making an animating main menu

What would be the best way to make a main menu for a game? I would prefer it to be UIButtons. More specifically, what would be the best way of animating the buttons? For example, an animation on the view load of the buttons going in, then the buttons going out when a menu option is selected and then new buttons (the submenu) animated back in. I have never done any animating before so I would like to know the best way. Thanks
This type of animation is very easy using UIKit:
[UIView animateWithDuration:0.5 animations:^{
button1.frame = <new frame>;
button2.frame = <new frame>;
}];
This will animate the frame from the current frame, to the specified frame over the given duration (0.5 seconds). If the current frame is offscreen and the new frame is the final position you want then the buttons will move to their correct position over 0.5 seconds.
The following properties of UIView are animatable in this fashion:
frame
bounds
center
transform
alpha
backgroundColor
contentStretch
The Animations section of the View Programming Guide has more info.

Blurred PNGs on UIView, using Interface Builder

I've added some UIImageViews with png images to my view, using interface builder. Initially they are added off-screen.
Later, I animate them onto the screen with CoreAnimation, like so:
[UIView beginAnimations:#"slide" context:nil];
[UIView setAnimationDuration:0.1f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:self];
image.frame = CGRectMake(81+1, 390, 150, 80);
[UIView commitAnimations];
Once they appear onscreen, they look really blurred or fuzzy.
I've heard of this happening before. Does anyone have any idea how to fix it?
Usually this means that you are positioning the views at fractional pixel values (e.g. 100.5). Make sure you round the coordinates of the position.
Quick fix: Re-order the object in the Objects pane on the left, i.e. send backward, then send forward again. Not sure why this happens, but it fixes it for me.
UIImageViews and other views can appear blurry in Interface Builder (and in your iPhone app) if the images are, as camdez suggests, not at rounded pixel locations. Fixing this can be tricky because Interface Builder will only display the numbers in the inspector as integers. However, let's say you have configured the "Origin" widget in the "View" inspector to allow you to specify the X and Y of the center of the view, rather than the top left. If your blurry view is centered at 100,100 and is 35 pixels high, Interface Builder will internally compute the top left corner of the view as (100-35/2) = 82.5 and write it to your XIB file as a decimal.
The quick fix:
Change the "Origin" widget back to the "Top Left" setting. Move the view within the canvas so that the pixel values are changed, and then type the correct values back in. Problem solved!