UIImage view animation problem - iphone

I have done the effect of playing lots of images like below:
NSInteger faceNum = 12;
NSMutableArray *faceArray = [[NSMutableArray alloc] initWithCapacity:faceNum];
for (int i = 1;i<faceNum+1; i++) {
NSString *facename = [[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat:#"animationFace%d",i] ofType:#"png"];
UIImage *faceImage = [UIImage imageWithContentsOfFile:facename];
[faceArray addObject:faceImage];
}
UIImageView *faceView = [[UIImageView alloc]
initWithFrame:CGRectMake(414, 157, 161, 124)];
faceView.animationImages = faceArray;
faceView.animationDuration = 30;
faceView.animationRepeatCount = 0;
[faceView startAnimating];
[self.view addSubview:faceView];
[faceView release];
[faceArray release];
And how to add the EaseInEaseOut effect to this.One picture disappear gradually,then another picture appear gradually.
Thanks

There is no inbuilt fade-in and out feature with imageview startAnimating. You can achieve this by manually setting the alpha of two view laid over each other:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5f];
imageviewToFadeOut.alpha = 0.0f;
imageviewToFadeIn.alpha = 1.0f;
[UIView commitAnimations];
and setImage manually alternatively to these UIViews.
[imageview setImage:image];
and to recursively call this method, use something like [self performSelector:#selector(methodname) withObject: afterDelay: ] inside the method itself.
Edit: For clarity, specifying the recursion to call this method over and over with delay:
-(void)methodname {
.. (do your task)
[self performSelector:#selector(methodname) withObject:NULL afterDelay:10 ];
}

Related

Within a UITableView cell, how can I lazy-load images which fade in?

How can I lazy load images in a UITableView cell, with a fade-in effect when the image is loaded?
SDImageWeb is a pretty good library which does what you need. It even has image cache, so once the images are downloaded, then next time they are picked from local flash memory.
What this does not do is fadeIn effect. But this is pretty easy to add, with UIView animations.
So to asynchronously download an image,
[imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]];
thats all..
To Put in fadein animation.
- (void)fadeInLayer:(CALayer *)l
{
CABasicAnimation *fadeInAnimate = [CABasicAnimation animationWithKeyPath:#"opacity"];
fadeInAnimate.duration = 0.5;
fadeInAnimate.repeatCount = 1;
fadeInAnimate.autoreverses = NO;
fadeInAnimate.fromValue = [NSNumber numberWithFloat:0.0];
fadeInAnimate.toValue = [NSNumber numberWithFloat:1.0];
fadeInAnimate.removedOnCompletion = YES;
[l addAnimation:fadeInAnimate forKey:#"animateOpacity"];
return;
}
To call this - [self fadeInLayer: imageView.layer];
This should do the trick. This animates, your image from alpha 0 to 1 in 0.5 seconds ! To give the wonderful fade in animation.
You are reffering to Asynchronous images. There is a great article available at: http://www.markj.net/iphone-asynchronous-table-image/
Within the connectionDidFInishLoading just put the later after this
UIImageView* imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease];
//Paste below code here
to fade it in:
//Paste following here
imageView.alpha = 0.0f;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5f];
imageView.alpha = 1.0f;
[UIView commitAnimations];

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

collision of two images, problem with the declaration

I have a method with an image "imageView":
- (void)createNewImageView {
// Get the view's frame to make it easier later on
UIImage *image = [UIImage imageNamed:#"abouffer_03.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// Add it at a random point
[imageView setCenter:[self randomPointSquare]];
[[self view] addSubview:imageView];
// Animate it into place
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:8.0f];
[imageView setCenter:CGPointMake(240, 160)];
[UIView commitAnimations];
[imageView release];
}
and another image "viewToRotate" (IBOuutlet defined in .h and interface builder)
And I want to check the collision with this method :
- (void)myRunloop
{
// check collision
if( CGRectIntersectsRect(imageView.frame, viewToRotate.frame) )
{
viewToRotate.alpha=0.2;
}
}
But xcode always give me the error :"imageView undeclared" and I don't know how to solve this . I don't wanna define it again in this method.
I just'd been through a similar problem actually when you set the frame of the imageView on line
[imageView setCenter:CGPointMake(240, 160)];
the imageView gets settled at that point in the memory, It's just that due to being in animation block it's showing you the transition that imageView is being moved towards the destination but in actual the view's coordinates are assigned with the destination location, you can confirm it by logging coordinates right after the line of code. If you really need to do this the similar way, you can use the timer instead of the animation block and animate yourself. But I circumvent this problem by using the animationDelegate. Just set animation delegate to self and define animationDidStopSelector and you're up. You're animationDidstopSelector will get fired when the animation's ended and hence the object reached it's final destination or you can say there's a collision (on UI). Hope that helps
Here's a code sample:
- (void)createNewImageView {
// Get the view's frame to make it easier later on
UIImage *image = [UIImage imageNamed:#"abouffer_03.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// Add it at a random point
[imageView setCenter:[self randomPointSquare]];
[[self view] addSubview:imageView];
// Animate it into place
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:)];
[UIView setAnimationDuration:8.0f];
[imageView setCenter:CGPointMake(240, 160)];
[UIView commitAnimations];
[imageView release];
}
your animationDidStopSelector will be just like:
-(void)animationDidStop:(id)sender {
//This is almost similar to collision detection, you can do something here
}
imageView is a local variable to the function createNewImageView and hence cannot be accessed by myRunloop
If you have declared imageView as an IBOutlet
you can set the image like this
UIImage *image = [UIImage imageNamed:#"abouffer_03.png"];
imageView.image = image
In Interface (.h file) declare like this
UIImageView *imageView;
And In your createNewImageView() method.Use the
imageView = [[UIImageView alloc] initWithImage:image];
You can assign a tag to the image view so you can find it later in the other method:
[imageView setTag:1];
// in myRunloop
UIImageView* imageView = [[self view] viewWithTag:1];

transition animation on only a part of the screen

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];
}

Annimation in iphone inside for loop not working

I am currently developing an application in iphone, i want to animate some images on screen and for the same i have written this code
for (int i = 1 ; i <= 5 ; i++)
{
imgview.image = [UIImage imageNamed: [NSString stringWithFormat:#"spleshScreen%d.png", 1]];
NSLog(#"i = %d" , i);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.9];
[UIView setAnimationRepeatCount:5];
[UIView setAnimationBeginsFromCurrentState:YES];
imgview.image = [UIImage imageNamed: [NSString stringWithFormat:#"spleshScreen%d.png", i]];
i++;
imgview.frame = CGRectMake(imgview.frame.origin.x, (imgview.frame.origin.y + 180), imgview.frame.size.width, imgview.frame.size.height);
imgview.frame = CGRectMake(imgview.frame.origin.x, (imgview.frame.origin.y - 350), imgview.frame.size.width, imgview.frame.size.height);
[UIView commitAnimations];
}
if i remove the for loop code works fine, but with for loop it's not working neither it get any error
Please let me know what can be the problem
You can use the animationImages property of a UIImageView to handle the animation for you.
Here is a code sample:
imageView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed: [NSString stringWithFormat:#"spleshScreen%d.png", 1]],
[UIImage imageNamed: [NSString stringWithFormat:#"spleshScreen%d.png", 2]],
[UIImage imageNamed: [NSString stringWithFormat:#"spleshScreen%d.png", 3]],
[UIImage imageNamed: [NSString stringWithFormat:#"spleshScreen%d.png", 4]],
[UIImage imageNamed: [NSString stringWithFormat:#"spleshScreen%d.png", 5]],
nil]; // Don't forget to nil terminate this array!
[imageView setAnimationDuration:2.0]; // Define the amount of time it takes to go through one cycle of all the images.
// The property animationRepeatCount default value is 0, which specifies to repeat the animation indefinitely.
[imageView startAnimating];
In the last 2 lines of your code, you were changing the y origin of the frame of your image (adding 180 then substracting 350 which doesn't really make sense).
As you didn't speak about it in your question, I leaved this out.
UIView Class Reference:
The animations are run in a separate thread and begin when the application returns to the run loop.
So when you start your loop you create some threads and there is may be problems with that.
Try to delete your for loop and use setAnimationDidStopSelector method (see the UIView Class Reference):
[UIView setAnimationDidStopSelector:#selector(annimationDidFinish:)];
When your annimationDidFinish is called you can invoke a method to start an "other loop".
I haven't tested this solution, but I just give you another track to help you.