Change images in UIImageView in sequence - iphone

I want make something like animation.
I have four UIImageView (names: IW1, IW2, IW3, IW4)
I want change image in IW1 on image1 and next on image2, after that change image in IW2 on image1 and next on image2, after that change image in IW3 on image1 and next image2, after that change image in IW4 on image1 and next on image2.
Unfortunately when I tried to do this, the only thing I could do is change the images in all UIImageViews at the same time, but I want to do it sequentially.
Someone will help?

I would do it this way
Header interface
int j;
int i;
UIImageView *imgV1;
UIImageView *imgV2;
UIImageView *imgV3;
UIImageView *imgV4;
UIImage *img1;
UIImage *img2;
NSArray *views;
NSArray *imgs;
Implementation
- (void)viewDidLoad{
i=0;
j=0;
views = [[NSArray alloc] initWithObjects:imgV1, imgV2, imgV3, imgV4, nil];
imgs = [[NSArray alloc] initWithObjects:img1, img2, nil];
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(changeImage) userInfo:nil repeats:YES];
}
-(void)changeImage{
UIImageView *imageView = [views objectAtIndex:j];
UIImage *image = [imgs objectAtIndex:i];
imageView.image = image;
i++;
if(i==2){
i=0;
j++;
if(j==4)
j=0;
}
}
Hope this helps (I didnt try it)

- (void)runSwitchImages
{
[UIView animateWithDuration:2 delay:2 options:UIViewAnimationCurveEaseInOut animations:^{
//Animate Image Change Here
} completion:^(BOOL finished) {
//When The Image is done animating it will go here
}];
}
You can use something like this to do the changes in series. You can create another one these functions for each images and have them call in series. Or Change the function to be recursive .
If you want it to continue to change us a NSTimer to call the function.

call this somewhere
[self performSelector:#selector(changeImage:) withObject:yourImageView afterDelay:1]
which will call this after a 1 second delay
-(void)changeImage:(UIImageView *)yourImageView
{
yourImageView.image = yourImage;
}

Related

UIImage view animate from one image to the next

I want to smothly animate an image in an UIImageView to turn into the next one within one second like UIModalTransitionStyleCrossDissolve does.
Currently, I've got an UIImageView * called "imageView" and a function which is called "imageForState" which returns me a UIImage * for the correct image.
So what I want to do is to animate the image A smoothly into image B if there is one.
Currently, my function is like that:
- (UIImage *) imageForState{
NSLog(#"state: %d", [save state]);
switch ([save state]) {
case 0:
case 1:
return [UIImage imageNamed:#"Sakuya_Debug.PNG"];
case 2:
return [UIImage imageNamed:#"Sakuya_2_Debug.PNG"];
default:
return NULL;
//Never called
}
}
-(void) tap{
[imageView setAnimationImages:[NSArray arrayWithObjects:[imageView image], [self imageForState], nil]];
imageView.animationDuration = 2.0;
[imageView startAnimating];
save.state++;
}
My problem is, that 1.) the animation goes on forever (when I set imageView.animationRepeatCount to 1, I end up at the first image again) and b.) the animation is not smooth; just like I would have used "setImage";
What am I doing wrong?
I suggest doing it with two imageViews and an animation block. In the following example I assume two square images with a siza of 100px. If you add the two imageViews as subviews make sure that imageB is added after imageA so it covers it.
Init the imageViews:
UIImageView *imageA = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Sakuya_Debug.PNG"]];
UIImageView *imageB = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Sakuya_2_Debug.PNG"]];
// hide the second image
imageB.alpha = 0.0;
// put the image with the same size at same position
imageA.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
imageB.frame = imageA.frame;
Blend method:
- (void)crossDissolveImageAtoB
{
[UIView animateWithDuration:1.0
animations:^{
imageB.alpha = 1.0;
}
completion:^(BOOL finished){
// do something after the animation finished,
// maybe releasing imageA if it's not used anymore...
}];
}

Move image from left to right

In my application after the view load, an image should appear from left to right.
I am writing this code in in viewdidload or viewwillappear:
UIImage *image = [UIImage imageNamed:#"PG05(REV).jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
for (int i=-1024; i<=0; i++) {
NSLog(#"i: %d",i);
sleep(5);
imageView.frame = CGRectMake(i,0, 1024, 768);
NSLog(#"done");
[self.view addSubview:imageView];
}
[imageView release];
But problem is that, before loading view it executes the above code than loads the view, so that it seems that view loaded and a static image is there.
But my requirement is that first view load completely then image should display from left to right.
Please help me out.
First of all, you should not call the -(void)addSubview: inside your for loop. You just need to call it once.
Secondly, if you want to animate your imageView from left to right, UIView class provides great functionalities for this using blocks.
Your code should look like this :
UIImage *image = [UIImage imageNamed:#"PG05(REV).jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(-1024, 0, 1024, 768);
[self.view addSubview:imageView];
[imageView release]; //Your imageView is now retained by self.view
//Animation
[UIView animateWithDuration:2.0
animations:^(void) {
imageView.frame = CGRectMake(0, 0, 1024, 768);
}];
The animateWithDuration: method will handle the animation timer for you, just set the duration argument according to your needs.
You can use a function and call it using timer method.
timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(moveImage) userInfo:nil repeats:NO];
-(void)moveImage
{
//Your condition
}
This is a job for UIView animations.
Put your imageView down at -1024 left, then go:
[imageView animateWithDuration:5 animations:^{
[imageView.frame = CGRectMake(0,0, 1024, 768)];
}];
Ta-da! A five second animation of your image sliding to the right.
Check out the animation methods of UIView (of which UIImageView is a subclass):
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html

UIImage view animation problem

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

Trying to reuse variable to avoid abandoned memory

I've got a TapDetectingImageView class that is pertaining in memory after usage because I do not reuse it in my code.
I change my code now to reuse it instead of re creating a new one each time.
The goal is to configure that TapDetectingImageView object and put it in a view. I'll do it 8 times but with the code below, only the last one is showing. I'm sure I'm missing something, but what? ;)
The view holding the imageViews is potatoeView. I'm adding new TapDetectingImageView through:
[potatoeView addSubview:imageView];
What's wrong in that code?
for (int i = 0; i <= numberOfPotatoes-1; i++)
{
NSLog(#"potatoesView Generation : %d",i);
NSArray *imgArray = [[NSArray alloc] initWithArray:[p objectAtIndex:i]];
UIImage *img1 = (UIImage *) [imgArray objectAtIndex:0];
UIImage *img2 = (UIImage *) [imgArray objectAtIndex:1];
NSString *imgName = (NSString *) [imgArray objectAtIndex:2];
if (imageView == nil) {
imageView = [[TapDetectingImageView alloc] initWithImage:img1 imageHighlighted:img2];
}else {
[imageView setImage:(UIImage *)img1];
[imageView setImageHighlighted:(UIImage *)img2];
}
[imageView setDelegate:self];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = [potatoesSize floatValue] ;
rect.size.width = [potatoesSize floatValue] ;
imageView.frame = rect;
[imageView setName:(NSString *)imgName];
imageView.tag = i+1; // tag our images for later use when we place them in serial fashion
NSValue *val = [potatoesSizeAndPositions objectAtIndex:i];
CGPoint point = [val CGPointValue];
imageView.center = point;
[potatoeView addSubview:imageView];
[imgArray release];
}
You seem to be fundamentally misunderstanding how your views are drawn. When you set up the same view instance with eight different positions and images, it doesn't "stamp" them all out on some canvas as it goes. Its state won't be queried until the main run loop gets around to drawing your view, at which point it'll ask your view for its frame and contents and so on to draw it. If you want to draw eight different images with UIViews, you'll need eight different views.
You only ever create one view, set it as the subview and then change it n-1 times. Drop the if (imageView==nil) and create all 8 of them.

adding image to array at runtime and clear it on button click

wat i am trying to is, each time user touches screen, i am adding a small bulletr image on screen
UIImage *img = [UIImage imageNamed:#"shoot_a.png"]; //bullet shot image
im.image = img;
[self.view addSubview:im];
, if user touches 50 times, there will be 50 images on screen.
now i want, if user hit a button, all these bullet should be remove from the screen.
i hope i am clear about my question.
[im removefromsuperview] doesnt work for me.
if i want to add images to array at run time, how can i add and release?
or is there any better way to clear all images
regards.
this is my touch method, i m adding bullet images on screen frm heere,, but these images are not getting added in Array
// Touch method
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(restrictTap == YES){
NSUInteger numTaps = [[touches anyObject] tapCount];
NSString *numTapsMessage = [[NSString alloc] initWithFormat:#"%i", numTaps];
[numTapsMessage release];
// getting location
CGPoint touchLocation = [[touches anyObject] locationInView:self.view];
NSString *locationMessage = [[NSString alloc] initWithFormat:#"Location: X = %.0f Y = %.0f", touchLocation.x, touchLocation.y];
//bullet shot image
im = [[UIImageView alloc] initWithFrame:CGRectMake(self.location.x, self.location.y, 12.0, 12.0)];
float j =self.location.x;
float i =self.location.y;
img = [UIImage imageNamed:#"shoot_a.png"]; //bullet shot image
im.image = img;
//im.hidden = NO;
[self.view addSubview:im]; ///bullet shot image is over transparent view
[imageArray addObject:img];
}
}
You could keep track of them via a NSMutableArray property and use that to remove them:
// create e.g. in initializer:
imageArray = [[NSMutableArray alloc] init];
// clean-up, e.g. in dealloc:
self.imageArray = nil;
// add image:
[imageArray addObject:im];
// remove all:
for (UIView *img in imageArray) {
[img removeFromSuperview];
}
[imageArray removeAllObjects];
You can set a particular tag to all the bullet imageViews when you add it to your view
im.tag = 1000;
and then on button touch, you can iterate through subviews array of your view and remove all views with that tag. something like :
int count = [[self.view subviews] count];
for(int i = 0; i < count; i++)
{
if([(UIView*)[[self.view subviews] objectAtIndex:i] tag] == 1000)
{
[(UIView*)[[self.view subviews] objectAtIndex:i] removeFromSuperview]
}
}