iPad - CGAffineTransformMakeRotation - keeping rotation - ios

I have a heads up display (HUD) that I'm trying to get to properly rotate with the view. I created a function orientationWillChange that is supposed to rotate the view and that works fine, just requires a little more programming on the side of the view controller implementing it.
My main problem is that it rotates when it closes. It does some other transformations when it closes (shrinking/fading it so it disappears), but it seems to be rotating it back to "normal".
I don't want to rotate the view another 90 degrees, I just want to make sure it stays in the rotation it is at. How do I do that?
My closing function is as follows:
- (void)close {
_windowIsShowing = NO;
[UIView animateWithDuration:0.125 animations:^{
hudView.transform = CGAffineTransformMakeRotation(rotationDegrees * M_PI / 180);
hudView.transform = CGAffineTransformMakeScale(1.1, 1.1);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.15 animations:^{
hudView.transform = CGAffineTransformMakeScale(0.4, 0.4);
hudView.alpha = 0.0;
backgroundColorView.alpha = 0.0;
} completion:^(BOOL finished) {
[hudWindow resignKeyWindow];
[self release];
}];
}];
}
(fyi this is based on CloudApp's HUD)

Related

Rotating Image multiple times and stopping at desired degree?

i had tried various method and couldn't figure out how to achieve this.i searched on internet a lot but can't figure out.
i have an ImageView (a wheel which spins) , i want to rotate it by 360 degree for 10 times(this is to just give user feel of fast turning wheel) , and then i want to rotate it by particular value say 90 degree( but it might be varying).
after this animation finishes i want to bring ImageView back to the initial position.
how do i achieve this ?
Thanks in advance.
well i found out how to do this.
i used below method to rotate by 360 degree for 10 times , and then rotate by particular degree.
-(void)rotate:(int)degreeToRotate
{
CGFloat radians = (M_PI/180) * degreeToRotate;
[UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations: ^{
//configuring to rotate 360 degree 10 times
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 ];
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = 10;
[_scoreImageView.layer addAnimation:rotationAnimation forKey:#"rotationAnimation"];
} completion:^(BOOL finished) {
//rotate by particular degree
[ UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
// -radians, to ensure clockwise rotation
self.scoreImageView.transform = CGAffineTransformMakeRotation(-radians);
} completion:^(BOOL finished) {
//method call to reset image original position
[self performSelector:#selector(resetPosition) withObject:nil afterDelay:3];
}];
}];
}
below method is used to reset image to original position.
-(void)resetPosition
{
[UIView animateWithDuration:0.2 animations:^() {
self.scoreImageView.transform = CGAffineTransformIdentity;
}];
}

Show scaled UIViewController in another UIViewController

I want to display a scaled down "preview" of another ViewController in another ViewController. Is this possible? No interaction are needed so it can basically be a screenshot, but scaled down. I can be solved by manually take a screenshot and save it as an image, but the ViewController contains a lot of localizations and are constantly updated, so if this can be done programatically.
https://www.dropbox.com/s/kd5vinrym1k7afk/Screenshot%202014-05-13%2015.20.17.png
Is this possible?
Edit: the sub view is stored in a storyboard
Edit: This is how I've solved it:
//Load the viewcontroller and view
previewViewController = [self.storyboard instantiateViewControllerWithIdentifier:[PLACEHOLDER_VIEWCONTROLLER_NAMES objectAtIndex:self.identifier]];
[self addChildViewController:previewViewController];
[self.placeholderView.superview addSubview:previewViewController.view];
previewViewController.view.transform = CGAffineTransformMakeScale(scale*2, scale*2);
CGPoint center = self.placeholderView.center;
center.y += 25;
previewViewController.view.center = center;
Use the viewController.view and then scale it down like:
viewController.view.transform = CGAffineTransformMakeScale(0.5, 0.5);
Add your another view controller view as subview to first viewcontroller
[UIView animateWithDuration:2.0f animations:^{
InnerView.userInteractionEnabled = NO;
//Always starts from original scale
InnerView.transform = CGAffineTransformMakeScale(0.5, 0.5);
//Incremental scale
//InnerView.transform = CGAffineTransformScale(InnerView.transform, 0.5, 0.5);
} completion:^(BOOL finished) {
NSLog(#"in Half size");
}];
[UIView animateWithDuration:2.0f animations:^{
InnerView.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
InnerView.userInteractionEnabled = YES;
NSLog(#"Normal size");
}];

iOS7 view transition effect zoomed in

Hi maybe this is a duplicated question and I just don't know the keyword to describe my question, if this is the case please point out.
I'm currently implementing a transition between two view, as the second view shows, it should looked like it's zoomed into the screen from outside, kind of fall on the screen. My idea is to zoom the second view 9 * original size and place the origin to -original_width, -original_height, and set alpha to 0. At the end I set alpha to 1 and show the original size.
so the following code is not working, the subviews are not resized. Could anyone tell me what I miss here or better show me some API which do the task?
[toVC.view setFrame:CGRectMake(0-fromVC.view.frame.size.width, 0-screenRect.size.height, fromVC.view.frame.size.width*3, fromVC.view.frame.size.height*3)];
for (UIView* view in toVC.view.subviews) {
CGRect frame = view.frame;
[view setFrame:CGRectMake(frame.origin.x*3, frame.origin.y*3, frame.size.width*3, frame.size.height*3)];
}
[toVC.view layoutIfNeeded];
[toVC.view setAlpha:0.1];
[UIView animateWithDuration:duration*5
animations:^{
[toVC.view setAlpha:1.0];
[toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
for (UIView* view in toVC.view.subviews) {
CGRect frame = view.frame;
[view setFrame:CGRectMake(frame.origin.x/3, frame.origin.y/3, frame.size.width/3, frame.size.height/3)];
}
}
completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
You could just set the view transform prior and after the transition:
CGAffineTransform scaleTransform = CGAffineTransformIdentity;
scaleTransform = CGAffineTransformScale(rotationTransform, 9., 9.);
view.transform = scaleTransform;
view.alpha = 0;
[UIView animateWithDuration:duration*5
animations:^{
view.transform = CGAffineTransformIdentity;
view.alpha = 1.;
}
}
completion:^(BOOL finished) {
}];

UIView will only animate once

I'm trying to animate an arrow spinning while my app downloads information. After each half spin, I want the app to check if the data has been downloaded yet. If not, the arrow should spin halfway again, with a short pause in between each spin.
-(void)animation {
[UIView animateWithDuration:0.7 delay:0 options:0 animations: ^{
imageView.transform = CGAffineTransformMakeRotation(180 * M_PI / 180);
} completion: ^(BOOL completed) {
if (completed && stillReloading) {
[self performSelector:#selector(animation) withObject:nil afterDelay:0.2];
}
}];
}
Even though the animation function is continually called, the image only rotates once. All calls made to the animation function after the first animation are ignored. Why is this? I don't want to set the repeat option on the animation as I do not know how many times the arrow will have the spin, and as I would like there to be a short pause between each spin.
This line
imageView.transform = CGAffineTransformMakeRotation(180 * M_PI / 180);
sets the angle to 180 degrees, and just that. The next time it's called same angle is used, so you see no animation.
If you want to rotate it again from its current position then you need to use a different method. CGAffineTransformMakeRotation makes a rotation from the identity transform. So what you end up with is this: Rotate to 180 degrees, rotate to 180 degrees, rotate to 180 degrees and the object never moves. Instead you need to use a method that applies the offset to the current transform. That is what the following method is for:
CGAffineTransformRotate(CGAffineTransform, CGFloat)
However, instead of applying it to CGAffineTransformIdentity as Saohooou's answer does, you should apply it to the current transform of your view.
Because you've made you view animate to angle (180 * M_PI / 180), it will never spring again if you set the same angle to it.
try this
CGFloat t = 180*M_PI / 180.0;
CGAffineTransform translateSpring = CGAffineTransformRotate(CGAffineTransformIdentity, t);
[UIView animateWithDuration:0.7 delay:0.0 options:nil animations:^{
imageView.transform = translateSpring;
} completion:^(BOOL completed) {
if (completed && stillReloading) {
//Use this method to let it spring back to its original angle
[UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
imageView.transform = CGAffineTransformIdentity;
} completion:NULL];
[self performSelector:#selector(animation) withObject:nil afterDelay:0.2];
}
}];
OR you can also set a dynamically update angle for your imageView to tranform into. See if it could help:)
Base on your problem, you can see my code, Here I use an animation to change the view back to its identity Transformation:
if (completed && stillReloading) {
//Use this method to let it spring back to its original angle
[UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
imageView.transform = CGAffineTransformIdentity;
} completion:NULL];
[self performSelector:#selector(animation) withObject:nil afterDelay:0.2];
}
// So if you want to transform it without getting seen, you can simply detele the animation code
if (completed && stillReloading) {
imageView.transform = CGAffineTransformIdentity;
[self performSelector:#selector(animation) withObject:nil afterDelay:0.2];
}
You will find that it is very difficult to get the arrow to rotate continuously clockwise in 180 degree increments. It will be simpler to rotate it in 90 degree increments.
You need to apply new rotation to the arrow's existing transform, to add more rotation each time.
-(void)animateArrowRotation {
[UIView animateWithDuration:0.35 delay:0 options:0 animations: ^{
imageView.transform = CGAffineTransformRotate(imageView.transform, M_PI_2);
} completion: ^(BOOL completed) {
if (completed && stillReloading) {
[self animateArrowRotation];
}
}];
}

CGAffineTransformScale and orientation change

Good evening,
I scale down a UIView by using CGAffineTransformScale.
[UIView animateWithDuration:0.3 animations:^{
gridContainerView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.2, 0.2);
gridContainerView.alpha = 0.0;
} completion:^(BOOL finished) {
// show UIView B
}];
and scale it back to its original size:
[UIView animateWithDuration:0.3 animations:^{
gridContainerView.transform = CGAffineTransformIdentity;
gridContainerView.alpha = 1.0;
} completion:^(BOOL finished) {
// remove UIView B
}];
This works fine. The gridContainerView get scaled down to the center of the screen. However, if I change the devices orientation (to a.e. landscape) the center is somehow shifted to the bottom left. The transformation is not going to the center of the screen anymore once I change orientation.
The only way to fix this is to release the gridContainerView and reallocate/init it. But unfortunately this is not an option for me at this point.
Any help is truly appreciated.

Resources