Flip and Rotate - ios

I have 2 views. I would like a card to flip and rotate along its axis to show the other view.
So when I click on view1, view1 should flip but flip in the sense that it rotates around the y-axis to show view 2.
I am using the FLIP directive in IOS, but that does not do the "rotate" that I am looking for:
[UIView transitionFromView:(self.displayingPrimary ? self.primaryView : self.secondaryView)
toView:(self.displayingPrimary ? self.secondaryView : self.primaryView)
duration: 2.0
options: (self.displayingPrimary ? UIViewAnimationOptionTransitionFlipFromLeft :
UIViewAnimationOptionTransitionFlipFromRight) | UIViewAnimationOptionShowHideTransitionViews
completion:^(BOOL finished) {
if (finished) {
self.displayingPrimary = !self.displayingPrimary;
}
}];

There are a couple of ways you can make one view flip to another using Quartz on iOS if you do not like the built in flip transformation. The following two code snippets both require you to #import <QuartzCore/QuartzCore.h> and also link against the QuartzCore framework. Note that both functions I wrote assume that both views are added as subviews with the same frame and one of them is hidden (setHidden:).
The first function will flip one view to another using 2D transformations. This is more efficient and all it really does is scale along the x axis. At high speeds, it looks pretty good, IMO.
+ (void)flipFromView1:(UIView*)v1 toView:(UIView*)v2 duration:(NSTimeInterval)duration completion:(void (^)(BOOL finished))completion
{
duration = duration/2;
[v2.layer setAffineTransform:CGAffineTransformMakeScale(0, 1)];
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
[v1.layer setAffineTransform:CGAffineTransformMakeScale(0, 1)];
} completion:^(BOOL finished){
[v1 setHidden:YES];
[v2 setHidden:NO];
}];
[UIView animateWithDuration:duration delay:duration options:UIViewAnimationOptionCurveEaseOut animations:^{
[v2.layer setAffineTransform:CGAffineTransformMakeScale(1, 1)];
} completion:completion];
}
The second function performs an actual 3D transformation. Note that if the views being rotated using this 3D transformation are over or under other subviews in 3D space then you could see those other views sticking through or getting hidden during this animation.
+ (void)flipFromView2:(UIView*)v1 toView:(UIView*)v2 duration:(NSTimeInterval)duration rToL:(BOOL)rToL completion:(void (^)(BOOL finished))completion
{
duration = duration/2;
v2.layer.transform = CATransform3DMakeRotation((rToL ? -1.57079633 : 1.57079633), 0, 1, 0);
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
v1.layer.transform = CATransform3DMakeRotation((rToL ? 1.57079633 : -1.57079633), 0, 1, 0);
} completion:^(BOOL finished){
[v1 setHidden:YES];
[v2 setHidden:NO];
}];
[UIView animateWithDuration:duration delay:duration options:UIViewAnimationOptionCurveEaseOut animations:^{
v2.layer.transform = CATransform3DMakeRotation(0, 0, 1, 0);
} completion:completion];
}

Related

How to repeat shake animation indefinitely or X times using animateWithDuration?

The code below came from this SO question: UIView shake animation.
This shake animation is perfect, except it stops after one iteration. How do you repeat the animation indefinitely, or how do you cause it to repeat it X times?
There are other SO answers on repeating UIView animations that suggest using CAKeyframeAnimation or CABasicAnimation, but this question is different. The goal is to reproduce this exact animation, with the "springy" effect from usingSpringWithDamping and initialSpringVelocity.
Using Autoreverse and Repeat don't reproduce the desired effect because the the initial translation is outside the animation block.
view.transform = CGAffineTransformMakeTranslation(20, 0);
[UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
view.transform = CGAffineTransformIdentity;
} completion:nil];
If you need exact same code few times than put that code in method and do recursion, something like that:
- (void)animateCount:(NSInteger)count {
if (count == 0) {
return;
}
view.transform = CGAffineTransformMakeTranslation(20, 0);
[UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
view.transform = CGAffineTransformIdentity;
} completion:^{
count--;
[self animateCount:count];
}];
}
Use (UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat) in options to repeat it indefinitely
[UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:1.0 options:(UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut) animations:^{
someView.frame = someFrame1;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5f animations:^{
someView.frame = someFrame2;
} completion:nil];
}];

iOS how to animate view scaling from the center of the view?

I'm using an affine transform within a repeating/reversing animation to create a "pulsing" effect. However, I noticed that the button gets shifted right when the animation begins. The anchor point for the button is at (0.5,0.5):
[UIView animateWithDuration:0.5
delay:0
options:UIViewAnimationOptionRepeat|
UIViewAnimationOptionAutoreverse|
UIViewAnimationOptionAllowUserInteraction|
UIViewAnimationCurveEaseInOut
animations:^{
self.recordButton.transform = CGAffineTransformMakeScale(1.2, 1.2);
} completion:^(BOOL finished) {
}];
It appears that when the transform is applied, the origin of the button's frame stays at the same spot.
How can I animate scale transform so the center of the button remains in the same spot once the transform is applied?
I usually play with the frame and CGRect utility functions
[UIView animateWithDuration:0.5
delay:0
options:UIViewAnimationOptionRepeat|
UIViewAnimationOptionAutoreverse|
UIViewAnimationOptionAllowUserInteraction|
UIViewAnimationCurveEaseInOut
animations:^{
self.recordButton.frame = CGRectInset(self.recordButton.frame, -1.2, -1.2);
} completion:^(BOOL finished) {
}];

Showing UIView with bouncy animation

I want to create a bouncy animation like in the Skitch application - when i press a button, a subview (simple view with several buttons) will appear from the side and will bounce a bit until it stops.
I can't find any standard animation that does that, so how i can implement this animation?
You can try this :
// Hide your view by setting its position to outside of the bounds of the screen
// Whenever you want, call this :
[UIView animateWithDuration:0.5
delay:0
usingSpringWithDamping:0.5
initialSpringVelocity:0
options:UIViewAnimationOptionCurveLinear
animations:^{
// Set your final view position here
}
completion:^(BOOL finished) {
}];
This method is the same as the usual animateWithDuration: but it introduces a spring animation.
Use UIView method:
+ (void)animateWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
usingSpringWithDamping:(CGFloat)dampingRatio
initialSpringVelocity:(CGFloat)velocity
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
This will do what you want
Use the UIView method, If you want bouncing effect. Then you need to nested the animation process and give the frame as needed for that view. Here's the example:
CGRect frameOnStart = CGRectMake(200,200 ,60 ,60); //On start show small view
CGRect frameOnAnimate = CGRectMake(80,80 ,150 , 150); //while animate show large view
CGRect frameAfterAnimate = CGRectMake(100,100,120 ,120); //after animate large take it back to original frame. SO it loos like bouncing animation
// Whenever you want, call this :
[UIView animateWithDuration:0.5
delay:0
usingSpringWithDamping:0.5
initialSpringVelocity:0
options:UIViewAnimationOptionCurveLinear
animations:^{
// Set your on Animate position here
view.frame = frameOnAnimate;
}
completion:^(BOOL finished) {
[UIView animateWithDuration:0.5
delay:0
usingSpringWithDamping:0.5
initialSpringVelocity:0
options:UIViewAnimationOptionCurveLinear
animations:^{
// Set your final view position here
view.frame = frameAfterAnimate;
}
completion:^(BOOL finished) {
}]
}];
Thanks.

How to make UIView move by click?

I'm not sure whether I can describe it properly. It's a kind of UIView, and we see only it's part (with arrow,maybe. on the bottom of screen,maybe). User can click on it, and this view appears fullscreen(usually developer leaves there some additional information). How can I make it?
Try this:
-(void)show
{
[viewObj setFrame:CGRectMake(viewObj.frame.origin.x,viewObj.frame.origin.y,viewObj.frame.size.width, viewObj.frame.size.height)];//Here "viewObj.frame.origin.y" means 568
[UIView animateWithDuration:0.5 animations:^
{
[viewObj setFrame:CGRectMake(viewObj.frame.origin.x,0,viewObj.frame.size.width, viewObj.frame.size.height)];
}
completion:^(BOOL finished)
{
}];
}
-(void)hide
{
[viewObj setFrame:CGRectMake(viewObj.frame.origin.x,viewObj.frame.origin.y,viewObj.frame.size.width, viewObj.frame.size.height)];//Here "viewObj.frame.origin.y" means 0
[UIView animateWithDuration:0.5 animations:^
{
[viewObj setFrame:CGRectMake(viewObj.frame.origin.x,568,viewObj.frame.size.width, viewObj.frame.size.height)];
}
completion:^(BOOL finished)
{
}];
}
i just put the logic that just setting of view Y coordinate of That View and when user click on Button. that et animation and at the re setting the view frame with Y coordinate setting like:
yourview.frame = CGRectMake(0,280,320,568);
[UIView animateWithDuration:2
delay:0.1
options: UIViewAnimationOptionTransitionFlipFromBottom
animations:^{
yourview.frame = CGRectMake(0, 0, 320, 568);
}
completion:^(BOOL finished){
}];
Also see this example:
https://github.com/crocodella/PullableView
Here above github demo this same that you are looking for its output like:
Look at UIView reference:
https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html
Specifically:
#property(nonatomic) CGPoint center
And
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations
Example:
[UIView animateWithDuration:2.0 animations:^{
myView.center = CGPointMake(self.view.center.x, self.view.center.y + myOffset);
}];
Duration is in seconds. In this case, 2 seconds.
If you're using AutoLayout, you probably want to change the layout constant, rather then center property.
About Layout Constrains:
https://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html
Look at constant property. You can also drag a constrain outlet from Interface Builder and access its constant. It's really simple once you get to know it a bit.

animateWithDuration:delay:options:animations:completion: not working (strangely)

I'm trying to translate a UIView for a distance using the following code:
CGAffineTransform transform = CGAffineTransformMakeTranslation(-100, -100);
[self.exposureHintView setTransform:transform];
[UIView animateWithDuration:2.0
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
NSLog(#"Begin!");
CGAffineTransform newTrans = CGAffineTransformMakeTranslation(0, 0);
[self.exposureHintView setTransform:newTrans];
}
completion:^(BOOL finished) {
NSLog(#"End %d", finished);
}];
So basically, I'm justing trying to move the view from some point say (-100, -100) to where it should be (0, 0) relative to itself.
Since I wanted to animate it once the view appeared, so I put the code in viewDidAppear:. But when I run the code, nothing happened.
The self.exposureHintView here is a custom subclass of UIView, does it matter?
Why?
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[_AboutView setFrame:CGRectMake(0, 0, 320, 510)];
[UIView commitAnimations];
Use this code to change the position of your view
I think the problem here is you are create exposureHintView in storyboard or XIB file without code programmatically.
Try to do as the follows:
- (void)viewDidLoad
{
//Init exposureHintView
UIView* exposureHintView = [[UIView alloc]initWithFrame(sampleFrame)];
[self addSubView: exposureHintView];
//Set transform
CGAffineTransform transform = CGAffineTransformMakeTranslation(-100, -100);
[self.exposureHintView setTransform:transform];
//Commit animation
[UIView animateWithDuration:2.0 delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
NSLog(#"Begin!");
CGAffineTransform newTrans = CGAffineTransformMakeTranslation(0, 0);
[self.exposureHintView setTransform:newTrans];
}
completion:^(BOOL finished) {
NSLog(#"End %d", finished);
}];
The reason here is your could not set Frame or Transform or some another attribute of this UIView in >>ViewDidLoad when you using storyboard or XIB

Resources