transition animation on only a part of the screen - iphone

I am displaying two images in my iPhone app, one on top, one on the bottom. They cover the entire screen. The user, with a swipe gesture, can change either of the images, depending on where the swipe started.
I want the image to change with an animated transition. It currently works without animation, or with the entire screen transitioning. Is it possible to make the transition occur over part of the screen?
I load the images for the first time (in viewDidLoad) thus:
// top image
UIImage *topImage = [UIImage imageNamed:#"top1.png"];
CGRect topframe = CGRectMake(0.0f, 0.0f, 320.0f, 240.0f);
UIImageView *topView = [[UIImageView alloc] initWithFrame:topframe];
topView.image = topImage;
[self.view addSubview:topView];
[topView release];
// bottom image
UIImage *bottomImage = [UIImage imageNamed:#"bottom1.png"];
CGRect bottomframe = CGRectMake(0.0f, 240.0f, 320.0f, 240.0f);
UIImageView *bottomView = [[UIImageView alloc] initWithFrame:bottomframe];
bottomView.image = bottomImage;
[self.view addSubview:bottomView];
[bottomView release];
When I detect a swipe, and detect which of the two images are to be changed, I call a routine like this one:
- (void)changeTopImage:(NSString *)newImage {
UIImage *topImage = [UIImage imageNamed:newImage];
CGRect topframe = CGRectMake(0.0f, 0.0f, 320.0f, 240.0f);
UIImageView *topView = [[UIImageView alloc] initWithFrame:topframe];
topView.image = topImage;
[self.view addSubview:topView];
[topView release];
}
Essentilly, I'm continually loading images on top of each other. Is that the best way to do it, especially in terms of memory management?
Everything else I've tried, using techniques such as below, make the entire screen transition:
[UIView beginAnimations:nil context:nil];
...
[UIView commitAnimations];
Thanks for any leads on which way I should be going on this.

well, an easy way could be this (repeat for the bottomImage):
don't release topView when you load it the first time in your method,
but declare it in your .h file,
and use a tempView too:
#interface YourClass: UIViewController{
UIImageView *topView;
UIImageView *tempView;
}
this way you can call them to move them and remove them when you load a new image
then in .m:
EDIT: some correction (see coco's comments):
[a] [b] line 4 = [c] line 11:
- (void)changeTopImage:(NSString *)newImage {
UIImage *topImage = [UIImage imageNamed:newImage];
//CGRect topframe = CGRectMake(0.0f, 0.0f, (320.0f + 320), 240.0f);
CGRect topframe = CGRectMake((0.0f + 320), 0.0f, 320.0f, 240.0f);
tempView = [[UIImageView alloc] initWithFrame:topframe];
//topView.image = topImage;
tempView.image = topImage;
[self.view addSubview:tempView];
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[UIView beginAnimations:#"animation" context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
tempView.center = topView.center;
// do this to push old topView away, comment next line if wanna new image just cover it
//topView.center = CGPointMake(topView.x - 320, topView.y);
topView.center = CGPointMake(topView.center.x - 320, topView.center.y);
// call a method when animation has finished:
[UIView setAnimationDidStopSelector:#selector(endOfAnimation:finished:context:)];
[UIView commitAnimations];
}
- (void)endOfAnimation:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
[topView removeFromSuperview];
topView = tempView;
[tempView release];
tempView = nil;
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
- (void)dealloc {
if (tempView != nil) {
[tempView release];
}
[topView release];
[super dealloc];
}

Related

How to move an array of images randomly in iphone app

How can I move an array of images randomly in iPhone app.
Bellow code is for moving one image. I've to use an array of images.
- (void)moveImage:(UIImageView *)image duration:(NSTimeInterval)duration
curve:(int)curve x:(CGFloat)x y:(CGFloat)y
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:YES];
// The transform matrix
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
image.transform = transform;
// Commit the changes
[UIView commitAnimations];
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIImageView *imageToMove =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"fish.png"]];
imageToMove.frame = CGRectMake(70, 120, 100, 100);
[self.view addSubview:imageToMove];
[self moveImage:imageToMove duration:1.0
curve:UIViewAnimationCurveLinear x:0.0 y:110.0];
}
you can use this it might help you:
NSArray *animationArray=[NSArray arrayWithObjects:
[UIImage imageNamed:#"img1.png"],
[UIImage imageNamed:#"img2.png"],
[UIImage imageNamed:#"img3.png"],
[UIImage imageNamed:#"img4.png"],
nil];
UIImageView *animationView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0,320, 460)];
animationView.backgroundColor=[UIColor purpleColor];
animationView.animationImages=animationArray;
animationView.animationDuration=1.5;
animationView.animationRepeatCount=0;
[animationView startAnimating];
[self.view addSubview:animationView];
[animationView release];
This is just a conceptual code so please make changes according to your need.

How to animate view from top to bottom?

In my app I want to launch UIViewController from top to bottom.So from FirstViewController I am launching MyWebViewController(which I need to animate) as follows:
MyWebViewController *theWebViewController = [[MyWebViewController alloc] initWithFrame:self.view.bounds];
[self.view addSubview:theWebViewController.view];
and In loadView of MyWebViewController I am assigning frame to view as follows;
- (void)loadView
{
CGRect theFrame;
theFrame = CGRectMake(0.0, 20.0, mFrame.size.width, 0.0);
UIView *view = [[UIView alloc] init];
view.frame = theFrame;
self.view = view;
[view release];
}
and In viewDidLoad I am changing the frame as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
[UIView beginAnimations:#"animateView" context: nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.5];
self.view.frame = CGRectMake(0.0, 20.0, mFrame.size.width, mFrame.size.height-20.0);
[UIView commitAnimations];
}
But the animation is not happening.I even tried this code to animate from bottom to top and it is working fine but vice-versa not working.Please can anyone tell me where I am doing wrong and how I can achieve?
Thanks in advance!
I wouldn't think to set the height to 0. Instead:
- (void)loadView
{
CGRect theFrame;
theFrame = CGRectMake(0.0, -mframe.size.height + 20, mFrame.size.width, m.frame.size.height - 20);
UIView *view = [[UIView alloc] init];
view.frame = theFrame;
self.view = view;
[view release];
}
You want to set the frame above and out of the view when you add it. Then move it into place in the animation.

Remove view 1 after replaced by view2

I have a small code to display image 1 and after 2 seconds replace image1 by image2 with animation below
UIImageView *view1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 410, 1020, 400)];
UIImage *image = [UIImage imageNamed:#"img.jpeg"];
view1.image = image;
[self.view addSubview:view1];
UIImageView *view2 = [[UIImageView alloc] init ];
view2.frame = CGRectMake(0, 410, 0, 400);
view2.image = [UIImage imageNamed:#"bien.jpeg"];
[self.view addSubview:view2];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.8];
[UIView setAnimationDelay:2];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(removeView: view1:)];
view2.frame = CGRectMake(0, 410, 800, 400);
[UIView commitAnimations];
and function removeView to remove view1 from superview below:
-(void)removeView: (UIImageView *)view1{
[view1 removeFromSuperview];
}
So i dont know why my function to remove view1 from superview not work, please help me! Thanks alot...
The selector cannot pass the parameter. Modify your method to
-(void)removeView{
[view1 removeFromSuperview];
}
where "view1" is a instance to your view.
and your selector to:
[UIView setAnimationDidStopSelector:#selector(removeView)];
I would recommend you to use block based animations (available since iOS 4).
They are much easier to use and don't need to send parameters through methods and all that stuff.
Example:
UIImageView *view1 = [[UIImageView alloc] init];
//initialize your UIImageView view1
[self.view addSubview:view1];
UIImageView *view2 = [[UIImageView alloc] init];
//initialize your UIImageView view2
[UIView animateWithDuration:2 animations:^{
//here happens the animation
[self addSubview:view2];
} completion:^(BOOL finished) {
//here happens stuff when animation is complete
[view1 removeFromSuperView];
}];
Remember to vote up and or mark as accepted answer ;)
Try this code!!
UIImageView *view1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 410, 1020, 400)];
UIImage *image = [UIImage imageNamed:#"img.jpeg"];
view1.tag = 1;
view1.image = image;
[self.view addSubview:view1];
UIImageView *view2 = [[UIImageView alloc] init ];
view2.frame = CGRectMake(0, 410, 0, 400);
view2.image = [UIImage imageNamed:#"bien.jpeg"];
[self.view addSubview:view2];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.8];
[UIView setAnimationDelay:2];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(removeView: view1:)];
view2.frame = CGRectMake(0, 410, 800, 400);
[UIView commitAnimations];
// Remove View Method
-(void)removeView : (UIImageView *) imgVew {
if (imgVew.tag == 1)
[imgVew removeFromSuperView];
}
Access it -
[UIView setAnimationDidStopSelector:#selector(removeView:)];
the problem is simple, this selector is not exists in your class: -removeView:view1:. thus there is nothing to call back after the animation finished. this is why your -(void)removeView:(UIImageView *)view1; method will be never called back.
please, realised your real selector is -removeView: and it is not equal with -removeView:view1:
if you want to pass parameter through the didStopSelector, I would have a bad news: you cannot do it as you did in your code, so this part is wrong at all:
// WRONG AT ALL:
[UIView setAnimationDidStopSelector:#selector(removeView:view1:)];
// PROPER WAY:
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
because the didStopSelector must be the following kind of selector with the following parameters.
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context;
you can pass parameter for your callback method like this:
[UIView beginAnimations:nil context:view1]; // see the context's value
and in your didStopSelector you can use it somehow like:
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
[((UIView *)context) removeFromSuperView];
}

How do I have images appearing randomly using NSTimer?

I've got a simple animation running and its moving up and down with a camera view as a background. I am trying to generate more animation at a random rate. Is that possible?
I am running my animation through UIView startAnimation.
NSArray *myImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"enemyball.png"],
[UIImage imageNamed:#"playerball.png"]
, nil];
//animation of images
UIImageView *animatedView =[UIImageView alloc];
[animatedView initWithFrame:[self bounds]];
animatedView.animationImages = myImages;
animatedView.animationDuration = 0.25; // seconds
animatedView.animationRepeatCount = 0; //0 loops for ever/noted
[animatedView startAnimating];
[self addSubview:animatedView];
//animation movement
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:1];
[UIView setAnimationRepeatCount:INFINITY];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationBeginsFromCurrentState:YES];
CGAffineTransform transform = CGAffineTransformMakeTranslation(220, 330);
animatedView.transform = transform;
[UIView commitAnimations];
And this is an overlay that I want to display in my camera view.
- (void) viewDidAppear:(BOOL)animated {
enemyBall *overlay = [[enemyBall alloc] initWithFrame:CGRectMake(20, 20, 50, 50)];
//OverlayView *overlay = [[OverlayView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH)];
// Create a new image picker instance:
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// Set the image picker source:
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Hide the controls:
picker.showsCameraControls = NO;
picker.navigationBarHidden = YES;
// Make camera view full screen:
picker.wantsFullScreenLayout = YES;
picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, CAMERA_TRANSFORM_X, CAMERA_TRANSFORM_Y);
// Insert the overlay:
//picker.cameraOverlayView = overlay;
picker.cameraOverlayView = overlay;
// Show the picker:
[self presentModalViewController:picker animated:YES];
[super viewDidAppear:YES];
}
I am trying to have my animation generate in a random sequence and timing but placing another set of array code seems too much and I can't have a second overlay because it doesn't read the second overlay. Is this possible?

Accessing the current position of UIView during animation

I am trying to find the current position of an iPhone ImageView that is animating across the screen.
I create and animate the imageView like so
-(IBAction)button:(UIButton *)sender{
UIImageView *myImageView =[[UIImageView alloc] initWithImage:
[UIImage imageNamed:#"ball.png"]];
myImageView.frame = CGRectMake(0, self.view.frame.size.height/2, 40, 40);
[self.view addSubview:myImageView];
[myArray addObject:myImageView];
[UIView animateWithDuration:.5
delay:0
options:(UIViewAnimationOptionAllowUserInteraction) // | something here?)
animations:^{
myImageView.frame = CGRectOffset(myImageView.frame, 500, 0);
}
completion:^(BOOL finished){
[myArray removeObject:myImageView];
[myImageView removeFromSuperview];
[myImageView release];
}
];
}
then to detect the current CGPoint of the imageView I call this method every 60th of a second
-(void)findPoint{
for (UIImageView *projectile in bullets) {
label.text = [NSString stringWithFormat:#"%f", projectile.center.x];
label2.text = [NSString stringWithFormat:#"%f", projectile.center.y];
}
}
However this only gives me the point where the animation ends, I want to get the current CGPoint of the image that is animating across the screen. Is there an option that I need to apply other than UIViewAnimationOptionAllowUserInteraction to do this? If not, how do I get the current position of an animating imageView?
You can use the presentationLayer - a property of the CALayer that "provides a close approximation to the version of the layer that is currently being displayed". Just use it like this:
CGRect projectileFrame = [[projectile.layer presentationLayer] frame];
Swift 5:
Get temporary position and size (CGRect) during the animation with:
let currentFrame = projectileFrame.layer.presentation()!.frame