Animating a group of UIView subviews continuously - ios

I am trying to show the movement of a vehicle on a road in my app. For this I am keeping my vehicle stationary and moving the lanes in the road from top to bottom continuously to create the effect. The lanes are added as subview to roadView and I am trying to animate all the subviews in the roadView as seen in the code below.
The problem I am facing is that the lane nearest to the bottom is moving at a faster speed compared the one at the top in the beginning although I am calculating the duration based on constant speed.
-(void)animateLanes {
for (UIView *laneView in [self.roadView subviews]) {
if (laneView.tag < 10) {
float distance = self.view.frame.size.height - CGRectGetMaxY(laneView.frame);
float duration = distance/10;
[UIView animateWithDuration:duration animations:^{
laneView.frame = CGRectMake(laneView.frame.origin.x, self.view.frame.size.height+laneView.frame.size.height, laneView.frame.size.width, laneView.frame.size.height);
} completion:^(BOOL finished) {
laneView.frame = CGRectMake(self.roadView.frame.size.width/2 - 10, -laneView.frame.size.height, 20, 40);
[self nextStep:laneView];
}];
}
}
}
-(void) nextStep:(UIView *) laneView{
float distance = self.view.frame.size.height - CGRectGetMaxY(laneView.frame);
float duration = distance/10;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionRepeat animations:^{
laneView.frame = CGRectMake(laneView.frame.origin.x, self.view.frame.size.height+laneView.frame.size.height, laneView.frame.size.width, laneView.frame.size.height);
} completion:^(BOOL finished) {
laneView.frame = CGRectMake(self.roadView.frame.size.width/2 - 10, -laneView.frame.size.height, 20, 40);
}];
}

I would most definitely look into SpriteKit for this kind of thing. The update loop in its SKScene will allow you to make sure everything is running smoothly.
However, if you do do this, you don't have to make all these UIView Animation calls. Do this:
//calculate duration and distance first, then:
[UIView animateWithDuration:duration animations:^{
for (UIView *laneView in [self.roadView subviews]) {
laneView.frame = CGRectMake(laneView.frame.origin.x, self.view.frame.size.height+laneView.frame.size.height, laneView.frame.size.width, laneView.frame.size.height);
}
} completion:^(BOOL finished) {
for (UIView *laneView in [self.roadView subviews]) {
laneView.frame = CGRectMake(self.roadView.frame.size.width/2 - 10, -laneView.frame.size.height, 20, 40);
[self nextStep:laneView];
}
}];
Although I do NOT advise doing any of this at all. Use a game library, namely SpriteKit because of its ease of integration and simplicity.

SpriteKit makes a lot more sense for this type of task, IMO. The logic would be similar and the objects would belong to SKScene instance which has a handy update method perfect for the loop effect you're aiming for.

Related

How i can do an uiimageView zoom animation linked to uiscrollview contentoffest?

I'm trying to achive an animation that zoom an imageview accordingly to a scrollview offset (i have seen something similar in spotify and some others apps). How i can do? I have tried something like:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (Scroll.contentOffset.y<-10 && Scroll.contentOffset.y>-20) {
[UIView animateWithDuration:0.1
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
ImageView.transform=CGAffineTransformMakeScale(1.1, 1.1);
}
completion:^(BOOL finished){
}];
}
if (Scroll.contentOffset.y<-20 && Scroll.contentOffset.y>-30) {
[UIView animateWithDuration:0.1
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
ImageView.transform=CGAffineTransformMakeScale(1.2, 1.2);
}
completion:^(BOOL finished){
}];
}
}
and so on until a value of 1.6 . Naturally this methods doesn't works well, it is called to many times and visually it jitters... I wanto to achive this result:
The user scroll down the scrollview while an image view placed in the background is scaled until an arbitray value (and a reverse behaviour when the user returns to scroll up). What is a correct approch?
Try setting the transform depending on the contentOffset without using animations, like
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat scale = 1;
if(Scroll.contentOffset.y<0){
scale -= Scroll.contentOffset.y/10; //calculate the scale factor as you like
}
ImageView.transform = CGAffineTransformMakeScale(scale,scale);
}

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.

Animating ImageView X position and resetting

I am wanting to animate a ImageView's X Position and reset it if it reaches a certain X Position. For example, Start out a 700 and move to the left.. if it reaches 100 I want to reset it to 700. And do this continually over and over.
Pretty sure a timer would be needed, but not sure how to go about this as this is my first IOS app. Searching google turned up alot of animation stuff, but all was different which led to confusion. :)
Use this code
call [self animate:your_image_view];
- (void)animate:(UIImageView*)your_image
{
if (need_to_animate)
{
CGRect from = CGRectMake(10, 100, 200, 200);
CGRect to = CGRectMake(10, 700, 200, 200);
[UIView animateWithDuration:2 animations:^{
your_image.frame = from;
} completion:^(BOOL finished) {
your_image.frame = to;
[UIView animateWithDuration:2 animations:^{
your_image.frame = from;
} completion:^(BOOL finished) {
[self animate:your_image];
}];
}];
}
}
See here how to use UIView animations iPhone UIView Animation Best Practice Alternatively set up a timer loop and then adjust the frame/center of your view

zoom animation using animation with block based methods

I have a zoom animation in which when I perform an action, a view comes up in a zooming fashion.
The code I use to do this is,
CGFloat xpos = self.view.frame.origin.x;
CGFloat ypos = self.view.frame.origin.y;
popContents.view.frame = CGRectMake(xpos+100,ypos+150,5,5);
[UIView beginAnimations:#"Zoom" context:NULL];
[UIView setAnimationDuration:0.8];
popContents.view.frame = CGRectMake(320, ypos-70, 350, 350);
[UIView commitAnimations];
[self.view.superview addSubview:popContents.view];
I just realized that in ios4.0 usage in this fashion is not recommended and animations using block based methods is recommended..
I tried looking for any sort of example which would give me a hint to get the zooming effect I need using the block based methods but I have not been able to find any...
It would be great if anyone could help me out in this...
i figured it out...
Apparently "zoom" is just a name and does not do anything( as far as I experimented with it)
Here is how I achieve the effect using animate with block based methods...
[UIView animateWithDuration:0.8 animations:^ { popContents.view.frame = CGRectMake(160, 70, 350, 350);
[self.view.superview bringSubviewToFront:self.view];
[self.view.superview addSubview:popContents.view]; }
completion: ^(BOOL finished) {
NSLog(#"DONE");
}
];
Now there is just 1 issue I am not able to figure out..
Here is the edited code -
[UIView transitionWithView:self.view duration:1
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^
{
popContents.view.frame = CGRectMake(160, 70, 350, 350);
[self.view.superview bringSubviewToFront:self.view];
[self.view.superview addSubview:popContents.view];
}
completion: ^(BOOL finished)
{
NSLog(#"DONE");
}];
so what happens here is that the table view rotates while the popContents view zooms to position.. I understand that is what will happen since I had given transitionWithView:self.view
however, how will I be able to add this effect to the popContents view ( the view which zooms to position)... is it possible?
I tried transitionWithView:popContents.view but that does not seem to have any additional effect to the zooming animation.
Could someone tell me what I am doing wrong?

iPad - CGAffineTransformMakeRotation - keeping rotation

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)

Resources