CATransform3D breaks UIView into two parts before animation - uiview

I have a problem with CATransform3D.
When I try to do a Y axis rotation, the UIView breaks into two parts before animation starts.
An image is worth a thousand words...
Here's the code:
CATransform3D _3Dt = CATransform3DMakeRotation(2.0 * M_PI, 0.0, 1.0, 0.0);
[UIView animateWithDuration:2.0
animations:^{
view.layer.transform = _3Dt;
}];
Any idea?
Thanks!

Solved!
The problem was the layer.zPosition
Here's is the final code:
view.layer.zPosition = CGRectGetWidth(view.bounds);
CATransform3D _3Dt = CATransform3DMakeRotation(2.0 * M_PI, 0.0, 1.0, 0.0);
[UIView animateWithDuration:2.0
animations:^{
view.layer.transform = _3Dt;
}];
Thanks!

Related

How to create Custom flip animation using UIView

I am trying to create a custom animation something like the default flip animation for a UIView, but without the actual flip, and also the axis of the flip I want to be on the left side not on the center. Here is an example of what I am trying to accomplish but without the repeat:
Also in the code I will add UILabel as sub view and a few more elements.
If you can provide a code example it will be much appreciated
Thank you very much in advance for any support!
Update:
used the example provided by #artal and obtained the wanted effect for UIImageView but how can I obtain the same example for an UIButton?
Tried the next code:
objectivesButton = [[UIButton alloc] initWithFrame:CGRectMake( 0.25f * [UIScreen mainScreen].bounds.size.width, 0.7f * [UIScreen mainScreen].bounds.size.height, 0.5f * [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height * 0.3f)];
[objectivesButton addTarget:self
action:#selector(startAnimationButton)
forControlEvents:UIControlEventTouchUpInside];
objectivesButton.backgroundColor = [UIColor yellowColor];
objectivesButton.layer.anchorPoint = CGPointMake(0, 0.5);
[self.view addSubview:objectivesButton];
- (void)startAnimationButton{
CATransform3D perspectiveTrasnform = CATransform3DIdentity;
perspectiveTrasnform.m34 = -0.004;
CGFloat rotateAngleDeg = 90;
CATransform3D flipTransform = CATransform3DRotate(perspectiveTrasnform, rotateAngleDeg / 180.0 * M_PI, 0, 1.5, 0);
[UIView animateWithDuration:3.0f animations:^()
{
objectivesButton.layer.transform = flipTransform;
}];
}
You can animate the view this way by applying a perspective and rotation transform to its underlying CALayer (a 3D transform).
To start it from the left side you can set the anchorPoint of the layer.
Here's an example:
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
imageView.center = CGPointMake(self.view.center.x - imageView.frame.size.width * 0.5, self.view.center.y + imageView.frame.size.height * 0.5);
imageView.layer.anchorPoint = CGPointMake(0, 1);
[self.view addSubview:imageView];
CATransform3D perspectiveTrasnform = CATransform3DIdentity;
perspectiveTrasnform.m34 = -0.004;
CGFloat rotateAngleDeg = 90;
CATransform3D flipTransform = CATransform3DRotate(perspectiveTrasnform, rotateAngleDeg / 180.0 * M_PI, 0, 1, 0);
[UIView animateWithDuration:5 animations:^()
{
imageView.layer.transform = flipTransform;
}];

Move image 90 degree using Bezier curve

I am new to iOS please some one help me to move image using Bezier curve along 90 degree path. I had searched but my doubt is not clear yet, So please help me.
I had tried this code but I would like to use Bezier curve.
- (void)startApp {
UIImageView *imageToMove =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"man.jpg"]];
imageToMove.frame = CGRectMake(10, 10, 100, 100);
[self.view addSubview:imageToMove];
// Move the image
[self moveImage:imageToMove
duration:1.0
curve:UIViewAnimationCurveLinear
x:70.0
y:70.0];
}
- (void)moveImage:(UIImageView *)image
duration:(NSTimeInterval)duration
curve:(int)curve
x:(CGFloat)x
y:(CGFloat)y {
// Setup the animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:YES];
// The transform matrix
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
image.transform = transform;
// Commit the changes
[UIView commitAnimations];
}
You can rotate (transform) view using CABasicAnimation also. I have done some calculation for that.
- (void) rotateAnimation {
CABasicAnimation *topAnimation = [CABasicAnimation animationWithKeyPath:#"transform"];
topAnimation.autoreverses = NO;
topAnimation.duration = 0.8;
topAnimation.repeatDuration = 0;
topAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DPerspect(CATransform3DMakeRotation(M_PI, 1, 0, 0), CGPointMake(0, 0), 400)];
[image.layer addAnimation:topAnimation forKey:nil];
}
And supporting methods for that rotation are below:
CATransform3D CATransform3DMakePerspective(CGPoint center, float disZ)
{
CATransform3D transToCenter = CATransform3DMakeTranslation(-center.x, -center.y, 0);
CATransform3D transBack = CATransform3DMakeTranslation(center.x, center.y, 0);
CATransform3D scale = CATransform3DIdentity;
scale.m34 = -1.0f/disZ;
return CATransform3DConcat(CATransform3DConcat(transToCenter, scale), transBack);
}
CATransform3D CATransform3DPerspect(CATransform3D t, CGPoint center, float disZ)
{
return CATransform3DConcat(t, CATransform3DMakePerspective(center, disZ));
}
About rotation is on X-axis (horizontal) on respective layer. You can change axis value to Y and Z from below line in rotateAnimation.
CATransform3DMakeRotation(M_PI, 1, 0, 0), CGPointMake(0, 0), 400)]
By changing 1, 0, 0 values to 0, 1, 0 in above code will change rotation on Y axis and similarly for Z axis. Replace values and have look for rotation you like.
Here is my UIImageView with IBOutlet named drawPad.
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150)
radius:100
startAngle:0
endAngle:(22.0f/7.0f)
clockwise:YES];
UIGraphicsBeginImageContext(self.view.frame.size);
path.lineCapStyle = kCGLineCapRound;
path.lineWidth = 10.0f;
[[UIColor blackColor] setStroke];
[path stroke];
self.drawpad.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

iOS: Applying CATransform3DRotate and CATransform3DScale does not have desired effect on MKMapView

In my app design I want to show tilted map (just like Apple 3D map but in pre-iOS 7 too). I am using transforms to achieve this but the results aren't satisfactory.
My annotations look skewed (I want them straight & facing user - not aligning with my map). Also after applying transform my map stops scrolling.
- (void) animateMap
{
[UIView animateWithDuration:0.8 animations:
^{
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -1200.0;
transform = CATransform3DRotate(transform, M_PI_4, 1.0, 0.0, 0.0);
CATransform3D transform1 = CATransform3DScale(transform, 1.33, 1.66, 0);
map.layer.transform = transform1;
}
completion:^(BOOL finished)
{
for (id ann in map.annotations)
{
[UIView animateWithDuration:0.8 animations:
^{
MKAnnotationView * annView = [map viewForAnnotation:ann];
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -1200.0;
transform = CATransform3DRotate(transform, -M_PI_4, 1.0, 0.0, 0.0);
annView.layer.transform = transform;
}];
}
}];
}

CATransform3D around all axis

I'm trying to create a kind of 'flip' animation that rotates a UIView 180 degrees around each axis, however, I am having trouble getting the desired effect. Here's what I've got so far:
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
CATransform3D tX= CATransform3DIdentity;
tX.m34 = 1.0 / -500;
CATransform3D tY= CATransform3DIdentity;
tY.m34 = 1.0 / -500;
CATransform3D tZ= CATransform3DIdentity;
tZ.m34 = 1.0 / -500;
tX = CATransform3DRotate(tX, M_PI, 1.0f, 0.0f, 0.0f);
tY = CATransform3DRotate(tY, M_PI, 0.0f, 1.0f, 0.0f);
tZ = CATransform3DRotate(tZ, M_PI, 0.0f, 0.0f, 1.0f);
self.flipView.layer.transform = CATransform3DConcat(tX, CATransform3DConcat(tY, tZ));
}
This however, doesn't appear to perform any animations, as if they are canceling eachother out. Seems like this should be a pretty straightforward task, but I can't seem to figure out how to combine each of those 3 animation conditions. Any help greatly appreciated! thanks
Rotating by a half-rotation (180° or π radians) about each of the three axes does, in total, result in no change (the concatenation of the three rotation transforms results in the identity transform).
Try rotating about just one axis to see what that does.

Sway Animation in iOS

I was wondering if it's possible to do some sort of sway animation in iOS. For example, a sway animation would be like a store sign blowing in the wind. think westerns. I would like to do this kind of animation when a button is pressed. I'm going for a western kind of feel and that would really put it over the top. Thanks in advance if you know how to do something like this.
In order to do this you have to do a couple of things beforehand such as setting the layer anchor point to (0.5,0.0). like the following:
swaybtn.layer.anchorPoint = CGPointMake(0.5, 0.0);
And then make a function that gets called when the button is tapped which starts the backwards sway animation, another which sways forward, and a last one that moves back to the original position. The degrees you specify is how far the sway will go and the second number in the rotationAndPerspectiveTransform is the direction the sway will go.
The functions are as follow:
-(void)sway:(id)sender{
CGFloat degrees = 50.0;
CALayer *layer;
layer = swaybtn.layer;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(moveForward)];
rotationAndPerspectiveTransform.m34 = 1.0 / -400;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, degrees * M_PI / 180.0f, -1.0f, 0.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
[UIView commitAnimations];
}
-(void)moveForward{
CALayer *layer;
layer = swaybtn.layer;
CGFloat degrees = 50.0;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
[UIView beginAnimations:#"swayforward" context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(moveBack)];
rotationAndPerspectiveTransform.m34 = 1.0 / -400;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, degrees * M_PI / 180.0f, 1.0f, 0.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
[UIView commitAnimations];
}
-(void)moveBack{
CALayer *layer;
layer = swaybtn.layer;
CGFloat degrees = 50.0;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
[UIView beginAnimations:#"moveback" context:NULL];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
rotationAndPerspectiveTransform.m34 = 1.0 / -400;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, degrees * M_PI / 180.0f, 0.0f, 0.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
[UIView commitAnimations];
}
And there you go. You should have an animation that sways an object back and forth just like a hanging sign.

Resources