How to rotate UIView using transform? - ios

I have a UIView which I am trying to transform (rotate) using the pitch value you can get from coremotion attitude. I am using transform however I am not sure my code is correct as the UIView is not doing anything.
This is my code its being called several times per second.
- (void)setLabelValueRoll:(double)roll pitch:(double)pitch yaw:(double)yaw
{
self.yLabel.text = [NSString stringWithFormat:#"pitch: %f", pitch];
CATransform3D transform;
transform = CATransform3DMakeRotation(pitch + M_PI_2, 1, 0, 0);
self.wapaA.layer.sublayerTransform = transform;
}
I am not sure how to set this part (pitch + M_PI_2, 1, 0, 0) to make the pitch affect my square UIView so it would I guess stay level as you tilt the phone back and forth.

It should be layer's transform property of UIView
wapaA.layer.transform = CATransform3DMakeRotation(pitch + M_PI_2, 1, 0, 0);

This will work
float degrees = 20; //the value in degrees
view.transform = CGAffineTransformMakeRotation(degrees * M_PI/180);

Related

UISliders overlap after transforming

I'm currently trying to create four vertical sliders in Objective-C. I'm able to rotate them using CGAffineTransform, but right now each slider is stacked on top of one another. How do you change the coordinates of the sliders so this doesn't happen?
Below is my code for rotating the sliders:
CGAffineTransform trans1 = CGAffineTransformMakeRotation(M_PI * 1.5);
_grainPitchSlider.transform = trans1;
CGAffineTransform trans2 = CGAffineTransformMakeRotation(M_PI * 1.5);
_grainOffsetSlider.transform = trans2;
CGAffineTransform trans3 = CGAffineTransformMakeRotation(M_PI * 1.5);
_grainDensitySlider.transform = trans3;
CGAffineTransform trans4 = CGAffineTransformMakeRotation(M_PI * 1.5);
_grainDurationSlider.transform = trans4;
Simply set the "center" of each slider, i.e. _grainPitchSlider.center = CGPointMake(x, y);

iOS Animated Bezier/Sine Curve

I am looking to animate a single-line bezier curve on a loop in iOS. The idea I have in my head resembles the Voice Control screen on the iPhone 4 before Siri. The curve does not need to react to anything ie. Audio, mic etc. It just needs to loop from screen left to screen right, and change the amplitude of the curve.
I have tried a couple tests and this is the closest I have come:
IOS : Animate transformation from a line to a bezier curve
I need to know how to animated the actual curve to appear as if it is moving, not just up and down.
If any one has some light to shed on this, that would be awesome!
Thanks!
Wow, I worked on the exact same thing today. :)
Check this :
So the view where I draw my waves, is initialized as :
_self_view = [[TDTWaveView alloc] initWithFrame:CGRectMake(-320, 174, 640, 200)];
Then in my viewDidLoad, I call [self animateWave]; once.
- (void)animateWave {
[UIView animateWithDuration:.5 delay:0.0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionCurveLinear animations:^{
_self_view.transform = CGAffineTransformMakeTranslation(+_self_view.frame.size.width/2, 0);
} completion:^(BOOL finished) {
_self_view.transform = CGAffineTransformMakeTranslation(0, 0);
}];
}
This gives the wave a sort of linear motion you might want.
As far as the code for the wave goes, I'll share the drawrect.
self.yc = 30//The height of a crest.
float w = 0;//starting x value.
float y = rect.size.height;
float width = rect.size.width;
int cycles = 7;//number of waves
self.x = width/cycles;
CGContextRef context = UIGraphicsGetCurrentContext();
CGMutablePathRef path = CGPathCreateMutable();
CGContextSetLineWidth(context, .5);
while (w <= width) {
CGPathMoveToPoint(path, NULL, w,y/2);
CGPathAddQuadCurveToPoint(path, NULL, w+self.x/4, y/2 - self.yc, w+self.x/2, y/2);
CGPathAddQuadCurveToPoint(path, NULL, w+3*self.x/4, y/2 + self.yc, w+self.x, y/2);
w+=self.x;
}
CGContextAddPath(context, path);
CGContextDrawPath(context, kCGPathStroke);

Rotate iOS Image Clockwise

I am trying to animate my image by having it rotate clockwise, and shrink down. So far, it is only going counter-clockwise. I have tried both positive and negative values for the value/Key path of rotating along Z, but it changed nothing.
[window addSubview:splashView];
[window bringSubviewToFront:splashView];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(startupAnimationDone:finished:context:)];
splashView.frame = CGRectMake(160, 284, 0, 0);
[splashView.layer setValue:[NSNumber numberWithInt:-360]
forKeyPath:#"transform.rotation.z"];
[UIView commitAnimations];
To rotate in specific direction more than 360°use CAKeyframeAnimation. There you can set not only the final value, but also some intermediate values.
// consider this to be pseudo code
keyFrameAnimation.values = #[ 90, 180, 270, 360, 450, 540, ... ];
I don't have any code to show you, but this is defnitely the way to do it.
Or just use M_PI directly.
M_PI_4 = 45 degrees
M_PI_2 = 90 degrees
M_PI = 180 degrees
M_PI*2 = 360 degrees
You can also set your transform more easily.
// set transform
splashView.layer.transform = CATransform3DMakeRotation(-M_PI*2, 0, 0, 1);
instead of
[splashView.layer setValue:[NSNumber numberWithInt:-360]
forKeyPath:#"transform.rotation.z"];
That's because you're passing degrees to the animation when it wants radians. Here's an example of how to make the conversion.
float degrees = 90.0f;
float radians = degrees * (180.0f / M_PI);

while performing dual operation on UIImageView

This time I am facing problem while performing dual operation on UIImageView means
1) Zoom+Flip the Image
2)Zoom + Reverse the Image
3)Zoom + Flip or Reverse + Rotate(+- 90)deg
so please help to find out the solution of this problem. In thiscase for Zoom I use the GuestureRecognizer for fliping+Revesing+Rotating UIImageView I Use the the UIButton for these operation so how I can handle these operations wiith combination on UIImage
what exact the problem When I Zoom In or Zoom Out the image the at the same time I want to rotate (+-90 deg) or Flip or Reverse the Image at exact zoom In or Zoom Out Position but that time Image get reset then perform the respective operation such rotate, flip ,reverse I wanted to do it simultaneously on UIImage
my code as
if (btnNames == "Rotate R")
{
Angle = deg + 90;
imgview.Transform = CGAffineTransform.MakeRotation (Angle * (float)Math.PI / 180);
return Angle;
} else
{
Angle = deg - 90;
imgview.Transform = CGAffineTransform.MakeRotation (Angle * (float)Math.PI / 180);
return Angle;
}
For Reverse
CGAffineTransform transform = CGAffineTransform.MakeScale (-1, 1);
imgView.Transform = transform;
return true;
============
For Flip
if (flips == false)
{
CGAffineTransform transform = CGAffineTransform.MakeScale (1, -1);
imgView.Transform = transform;
return true;
}
this code i implemented it works fine individually perform to operation. But I want to work simultaneously on UIImage
I would recommend:
Place the UIImage in a UIScrollView with zooming setup
Modify your UIImage's Transform for reverse, rotate, etc.
To setup zooming:
yourScroller.MaximumZoomScale = 5;
yourScroller.MinimumZoomScale = 1;
yourScroller.ViewForZoomingInScrollView = _ => yourImage;
An example for rotation would be:
yourImage.Transform.Rotate (Math.PI / 2)
Play around with it, the UIScrollView should modify the same Transform on the image, so everything should work in tandem.
I'm not sure I really understand what you mean, but it sounds like your trying to do more the one transformations for an image by setting the UIView's transform property like this (example):
myView.transform = scale;
myView.transform = flip;
myView.transform = rotate;
What happens then is, that only the last one of these "is active: on the view.
What you should do is "keeping/saving" the current transformation and appending the new one with CGAffineTransformConcat like:
myView.transform = scale;
myView.transform = CGAffineTransformConcat(myView.transform, flip);
myView.transform = CGAffineTransformConcat(myView.transform,rotate);
Keep in mind that for some transformations order of concatenation matters!
Transformations can be combined by applying them to an existing transformation:
CGAffineTransform transform = CGAffineTransformIdentity;
// Rotate
if (btnNames == "Rotate R") {
Angle = deg + 90;
transform = CGAffineTransformRotate(transform, Angle * (CGFloat)Math.PI / 180);
} else {
Angle = deg - 90;
transform = CGAffineTransformRotate(transform, Angle * (CGFloat)Math.PI / 180);
}
// Reverse
transform = CGAffineTransformScale(transform, -1, 1);
// Flip
if (!flips) {
transform = CGAffineTransformScale(transform, 1, -1);
}
// Apply combined transformation
imgView.transform = transform;

How to animate UIImageViews like hatch doors opening

I'm trying to create an animation that would look like 2 french doors (or 2 hatch doors) opening towards the user.
I tried using the built in UIViewAnimationOptionTransitionFlipFromRight transition, but the origin of the transition seems to be the center of the UIImageView rather than the left edge. Basically I have 2 UIImageViews that each fill have the screen. I would like the animation to look like the UIImageViews are lifting from the center of the screen to the edges.
[UIView transitionWithView:leftView
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^ { leftView.alpha = 0; }
completion:^(BOOL finished) {
[leftView removeFromSuperview];
}];
Has anyone done something like this before? Any help would be awesome!
UPDATE:
Working code thanks to Nick Lockwood
leftView.layer.anchorPoint = CGPointMake(0, 0.5); // hinge around the left edge
leftView.frame = CGRectMake(0, 0, 160, 460); //reset view position
rightView.layer.anchorPoint = CGPointMake(1.0, 0.5); //hinge around the right edge
rightView.frame = CGRectMake(160, 0, 160, 460); //reset view position
[UIView animateWithDuration:0.75 animations:^{
CATransform3D leftTransform = CATransform3DIdentity;
leftTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
leftTransform = CATransform3DRotate(leftTransform, -M_PI_2, 0, 1, 0);
leftView.layer.transform = leftTransform;
CATransform3D rightTransform = CATransform3DIdentity;
rightTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
rightTransform = CATransform3DRotate(rightTransform, M_PI_2, 0, 1, 0);
rightView.layer.transform = rightTransform;
}];
First add the QuartzCore library to your project and #import <QuartzCore/QuartzCore.h>
Every view has a layer property with sub-properties that are animatable. This is where you'll find all the really cool stuff when it comes to animation capabilities (I suggest reading up on the CALayer class properties you can set - it will blow your mind - dynamic soft drop shadows on any view?)
Anyway, back on topic. To rotate your doors open in 3D, first position them as if they were closed, so with each door filling half the screen.
Now set their view.layer.anchorPoint properties as follows
leftDoorView.layer.anchorPoint = CGPoint(0, 0.5); // hinge around the left edge
rightDoorView.layer.anchorPoint = CGPoint(1.0, 0.5); // hinge around the right edge
Now apply the following animation
[UIView animateWithDuration:0.5 animations:^{
CATransform3D leftTransform = CATransform3DIdentity;
leftTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
leftTransform = CATransform3DRotate(leftTransform, M_PI_2, 0, 1, 0); //rotate 90 degrees about the Y axis
leftDoorView.layer.transform = leftTransform;
//do the same thing but mirrored for the right door, that probably just means using -M_PI_2 for the angle. If you don't know what PI is, Google "radians"
}];
And that should do it.
DISCLAIMER: I've not actually tested this, so the angles may be backwards, and the perspective may be screwy, etc. but it should be a good start at least.
UPDATE: Curiosity got the better of me. Here is fully working code (this assumes that the left and right doors are laid out in the closed position in the nib file):
- (void)viewDidLoad
{
[super viewDidLoad];
leftDoorView.layer.anchorPoint = CGPointMake(0, 0.5); // hinge around the left edge
leftDoorView.center = CGPointMake(0.0, self.view.bounds.size.height/2.0); //compensate for anchor offset
rightDoorView.layer.anchorPoint = CGPointMake(1.0, 0.5); // hinge around the right edge
rightDoorView.center = CGPointMake(self.view.bounds.size.width,self.view.bounds.size.height/2.0); //compensate for anchor offset
}
- (IBAction)open
{
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0f/500;
leftDoorView.layer.transform = transform;
rightDoorView.layer.transform = transform;
[UIView animateWithDuration:0.5 animations:^{
leftDoorView.layer.transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
rightDoorView.layer.transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
}];
}
- (IBAction)close
{
[UIView animateWithDuration:0.5 animations:^{
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0f/500;
leftDoorView.layer.transform = transform;
rightDoorView.layer.transform = transform;
}];
}

Resources