Move image left to right continuously - ios

I need to make run this animation from left to right continuously. Now Is working, but show 1 time only (when the game is loaded). I want to make this animation run continously, left to right continuously. Timer and speed is already working. Here my current code:
- (void)airplane1Code {
airplane1.center = CGPointMake(airplane1.center.x + 10, airplane1.center.y);
}
Any suggestion? Thanks

You can create a UIView animation with the UIViewAnimationOptionRepeat
airplane1.center = CGPointMake(startX, startY);
[UIView animateWithDuration:10.0 //10seconds
delay: 0
options: UIViewAnimationOptionRepeat
animations:^{
airplane1.center = CGPointMake(endX, endY);
}
completion:nil];
That will make it do the same animation from start to end over and over. In order to stop the animation, call
[airplane1.layer removeAllAnimations];

If you want the airplane to show up on the start side after it disappears from the end side, just reset the center off screen on the start side once it passes the window's frame. If you want another plane to show up and start flying after that one has left, then add another plane object and move them at the same time.
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
-(void) airplane1Code{
airplane1.center = CGPointMake(airplane1.center.x + 10, airplane1.center.y);
if(airplane1.center > screenWidth + halfTheImageSize)
// if the plane is completely off the screen, move the image to other side
// and keep running this method with your loop
airplane1.center = CGPointMake(0 - halfTheImageSize, airplane1.center.y);
}

Related

box flip 3D animation for side menu

I have scrollview and inside scrollview I have 2 views as MainView and another as SideMenuView.
What I want to make animation like below.
Any idea what needs to be done to get this working?
Psuedo Code below:
- (void)animateSideMenu{
homeView.frame = CGRectMake(sideMenuWidth, 0.0, (self.view.frame.size.width - sideMenuWidth), self.view.frame.size.height);
[UIView animateWithDuration:1.0 delay:0.0
options:UIViewAnimationOptionCurveLinear
animations:^{
sideMenu.frame = CGRectMake(0.0, 0.0, sideMenuWidth, sideMenuHeight);
[self flipAnimation];
} completion:^(BOOL finished) {
}];
}
- (void)flipAnimation{
CABasicAnimation *yRotate = [CABasicAnimation animationWithKeyPath:#"transform.rotation.y"];
yRotate.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 0, 1, 0)];
yRotate.toValue = #(M_PI * 1.5);
yRotate.duration = 0.5;
yRotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[sideMenu.layer addAnimation:yRotate forKey:#"yRotate"];
}
Below are the steps to develop this type of animation:
set the frame of homeView(Red colour view) of screen size & add pan gesture to this view.
set frame of sideMenu view in negative x-axis.
Create a responder function for pan gesture recogniser, in this function call the above mentioned animateSideMenu function.
Adjust the animation parameters accordingly.
Try with this & let me know if anything comes up.
I would not use a scrollview but rather a UIPanGestureRecognizer in which I would detect your current "pan offset" and calculate a current fraction of the animation and positions of those two views (let's simplify it so that the menu is view1 and the rest view2).
Then I would simply set an appropriate transform in the .Changed state.
In .Ended state I would see whether the menu is closer to being open or close and create an animation with .toValue set accordingly. You should use CAAnimations or better - Facebook pop animations because you can pause and remove them and the views stay put and not jump to their initial positions (as is often the case with UIViewAnimate).
If you need help with writing exact code you can write here and I'll edit my answer.
There's tutorial for exactly that menu, though it's in Swift:
https://www.raywenderlich.com/87268/3d-effect-taasky-swift

Recursive animation not working as it should

I have an animation that is first called once a button is tapped, and once it completes I have the animation run again by calling the method that the animation is in again and passing a "TRUE" value. However, when I stop the animation and call it again when I need to it runs faster and faster even though I have the same code (it gets to a point where it completes the whole loop in less than 1 second, and it should take about 10-20 seconds.) Could anyone explain what I need to do to have the animation simply reset itself after I need it to stop?
Also, after I pass a "FALSE" that should stop the animation, I reset the frame of the label I am moving, but that doesn't seem to show when I run the animation again as sometimes it starts in the middle of the screen when it should begin at the left of the screen.
Here is the code:
-(void)updateLabel:(BOOL)startStop
{
CGFloat CGRectGetMinY ( CGRect rect );
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
if(startStop)
{
[UIView animateWithDuration:1.0f
animations:^{
progress.frame= CGRectMake(progress.frame.origin.x+20.0f, progress.frame.origin.y, progress.frame.size.width, progress.frame.size.height);
} completion:^(BOOL finished) {
[self updateLabel:true];
}];
} else {
[self.view.layer removeAllAnimations];
progress.frame= CGRectMake(0.0f, progress.frame.origin.y, progress.frame.size.width, progress.frame.size.height);
}
}
try this...
instead of passing 'false' to the method, change it so it checks a global variable to see if it should run or not
//'doTask' is previously defined in your program
//set 'doTask' to false when you want the recursion to stop
//and set 'doTask' back to true before calling this again
-(void)recursiveMethod{
if(doTask){
//do something
[self recursiveMethod];
}
else{
//re-set anything that
//needs to be re-set
}
}

Stopping UIViewAnimation with removeAllAnimations

I have a simple UILabel that starts rotating when you do a long-press on it. I'm achieving this successfully using the following code:
-(IBAction)longPressEffect:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) {
UIViewAnimationOptions animationOptions = UIViewAnimationCurveLinear | UIViewAnimationOptionRepeat;
[UIView animateWithDuration:0.4 delay:0.0 options:animationOptions animations:^ {
labelObject.transform = CGAffineTransformMakeRotation(DegreesToRadians(angle));
} completion:nil];
angle = angle + 180;
}
else if (sender.state == UIGestureRecognizerStateEnded) {
;
}
}
The user can stop this animation at any point by simply double-clicking on the Label. Here's the code for that:
-(IBAction)doubleTapEffect:(UITapGestureRecognizer *)sender {
[labelObject.layer removeAllAnimations];
labelObject.transform = CGAffineTransformMakeRotation(DegreesToRadians(0));
}
The problem is that the next time you do long-press on the Label - it doesn't respond. The rotation animation doesn't start up again. You to have to click on it yet one more time to get it going again.
So the pattern is:
1) Long press - animation starts
2) Double click - animation stops
3) Long Press - nothing happens
4) Long press yet again - animation starts up again.
How do I fix this?
It is animating - it just doesn't look as if it is, because you are adding 180 to the angle all the time.
Assuming that angle is 180 to start with, you animate from 0 to 180 then 180 around to 180 then 180 around to 180. Then angle is + 180, which puts angle at 360, and the initial animation is 360, which is interpreted as 0, so the label animates from 0 to 0.
Change
angle = angle + 180;
to
angle = angle + 30;
and you should see the rotation happening.
This link might help you do a continuous rotation, if that's what you're trying to do:
How can I rotate a UIButton continuously and be able to stop it?

UIView to make an arm wave

I'm trying to make an arm wave effect (Hello!) with UIView animations, but it snaps back to the beginning when the last one goes off. I want the wave to go back and forth.
First keyframe: Rotation 30˚
Second keyframe: Rotation -30˚
Third keyframe: SHOULD BE Rotation 0˚
arm.layer.anchorPoint = CGPointMake(1.0, 1.0);
float x = arm.frame.origin.x + arm.frame.size.width;
float y = arm.frame.origin.y + arm.frame.size.height;
arm.layer.frame = CGRectMake(x, y, arm.frame.size.width, arm.frame.size.height);
[self.scrollView arm];
float degrees = 30.0;
float radians = (degrees/90.0)*M_PI;
[UIView animateKeyframesWithDuration:4.0f delay:0.0 options:UIViewKeyframeAnimationOptionRepeat
animations:^{
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.5 animations:^{
arm.transform = CGAffineTransformMakeRotation(radians);
}];
[UIView addKeyframeWithRelativeStartTime:.5 relativeDuration:.75 animations:^{
arm.transform = CGAffineTransformMakeRotation(-radians);
}];
[UIView addKeyframeWithRelativeStartTime:1.25 relativeDuration:.5 animations:^{
arm.transform = CGAffineTransformMakeRotation(0);
}];
The reason is that you used up the whole animation on the first two frames of the keyframe animation. These are relative times and relative durations; they must all be less than 1!
So, on the first one you use up half the animation (.5).
On the second one you start halfway through the animation (.5) and then you use up the entire rest of the animation (.75 is larger than .5 which is all you've got left).
So the third one never happens. And in any case it's completely nuts: you can't have a relative start time of 1.75 because 1 is the end of the animation. Read the docs:
This value must be in the range 0 to 1, where 0 represents the start of the overall animation and 1 represents the end of the overall animation. For example, for an animation that is two seconds in duration, specifying a start time of 0.5 causes the animations to begin executing one second after the start of the overall animation.

rotate UIImageView around an arbitrary point

I have a UIImageView that I rotate around its center:
imageHorizon.layer.anchorPoint = CGPointMake(0.5, 0.5);
imageHorizon.transform = CGAffineTransformRotate(imageHorizon.transform, angleToRotate*(CGFloat)(M_PI/180));
Sometimes I also move this image to the left or right and then rotate again. I would like to keep the rotation center all the time on the same point (which is actually the center of the super view). How can I do that ?
cheers,
self.imgView.layer.anchorPoint = CGPointMake(0.0,1.0);
self.imgView.layer.position = CGPointMake(100,200.0);
CGAffineTransform cgaRotateHr = CGAffineTransformMakeRotation(-(3.141/4));
[self.imgView setTransform:cgaRotateHr];
This is an older question, but the other solutions did not work well for me, so I came up with another solution:
Rotating an image is essentially just a normal rotation with a translation applied, ensuring that the point you want to rotate around is still in the same spot after the rotation. To do this, calculate the position's CGPoint in your image before the rotation, get the position after the rotation, and apply the difference as a translation on the image, "snapping" it into the right position. Here is the code that I've been using:
Keep in mind that the translation should be applied via CGAffineTransform, not moving the .center, because the translation will need to be relative to the rotation, and CGAffineTransformTranslate() takes care of that.
// Note: self is the superview of _imageView
// Get the rotation point
CGPoint rotationPointInSelf = self.center; // or whatever point you want to rotate around
CGPoint rotationPointInImage = [_imageView convertPoint:rotationPointInSelf fromView:self];
// Rotate the image
_imageView.transform = CGAffineTransformRotate(_imageView.transform, angle);
// Get the new location of the rotation point
CGPoint newRotationPointInImage = [_imageView convertPoint:rotationPointInSelf fromView:self];
// Calculate the difference between the point's old position and its new one
CGPoint translation = CGPointMake(rotationPointInImage.x - newRotationPointInImage.x, rotationPointInImage.y - newRotationPointInImage.y);
// Move the image so the point is back in it's old location
_imageView.transform = CGAffineTransformTranslate(_imageView.transform, -translation.x, -translation.y);
You can make the image a subview of another view and then rotate the superview to get that effect. Another approach is to set the anchorPoint property as described in the docs.
I'm using this code to rotate around the point (0,0).
Maybe it help you figure out how to active what you want.
float width = self.view.frame.size.width;
float height = self.view.frame.size.height;
CGRect frame_smallView = CGRectMake(-width, -height, width, height);
UIView *smallView = [[UIView alloc] initWithFrame:frame_smallView];
smallView.backgroundColor = darkGrayColor;
// Select x and y between 0.0-1.0.
// The default is (0.5f,0.5f) that is the center of the layer
// (1.0f,1.0f) is the right bottom corner
smallView.layer.anchorPoint = CGPointMake(1.0f, 1.0f);
// Rotate around this point
smallView.layer.position = CGPointMake(0, 0);
[self.view insertSubview:smallView belowSubview:self.navBar];
[UIView animateWithDuration:1
animations:^{
smallView.transform = CGAffineTransformMakeRotation(M_PI);
}
completion:^(BOOL finished){
[self.navigationController popViewControllerAnimated:NO];
}];

Resources