views:

162

answers:

4

Hi, all!

I'm developing a game in which I want my image to reduce in size gradually. I'm reducing the frame size gradually in my code when it works fine. [I've already used CGAffineTransform and it doesn't suit my requirement.]

-(void)function     
{
    ravanImage1.frame=CGRectMake(150,((ravanImage1.frame.origin.y)-5),q,z);

    if(ravanImage1.center.y>=300&&ravanImage1.center.y<=370)
    {
        q=60;
        z=60;
        ravanImage1.frame=CGRectMake(150,((ravanImage1.frame.origin.y)-5),q,z);
    }   

    if(ravanImage1.center.y>=230&&ravanImage1.center.y<=299)
    {
        q=40;
        z=40;
        ravanImage1.frame=CGRectMake(150,((ravanImage1.frame.origin.y)-5),q,z);
    }

    if(ravanImage1.center.y>=150&&ravanImage1.center.y<=229)
    {   
        q=20;
        z=20;
        ravanImage1.frame=CGRectMake(150,((ravanImage1.frame.origin.y)-5),q,z);
    }
}

But when I apply a while loop for the same code specifying wheather at what point to stop reducing the frame("while that point isn't reached"), it doesn't show the image frame reduction little by little as it shows it otherwise, but directly places the image at the end point with proper frame. I want it to get displyed the way it gets without the while loop i.e. reduction little by little. Yes, while debugging it steps through all the steps properly. Can anybody please help me?

+1  A: 

The reason it does that is because it executes the while loop very quickly. I think the best thing to do is put some sort of a delay timer after each step of the while loop, then you'll see each step and it won't just 'jump' to it's final state.

Tony
Can you please tell me how do you apply delay timer? Or you mean to apply a normal timer calling the same function after some delay?
neha
is this coded in Objective C?
Tony
Yes, Tony.. It's coded in Objective-C.
neha
A: 
[self setTimer: [NSTimer scheduledTimerWithTimeInterval: 3.5
                                                                    target: self
                                                                  selector: @selector (function_name)
                                                                  userInfo: nil
                                                                   repeats: YES]];

try using this.

Nithin
declare as NSTimer *timer;and set its property, synthesize it.note that timer is defined and setTimer is used in funtion, t->T
Nithin
neha
Also, all my code works on the same thread, so none of the thread delay methods can work, as it delays my entire code, which I dont want. I just want to delay something in entire code.
neha
+1  A: 

As others have pointed out, manually adjusting the frame of your view will give you terrible performance. If you really don't want to use a standard UIView animation block for changing your view, you can specify bounds size values to animate through using a CAKeyframeAnimation applied to your view's layer:

CAKeyframeAnimation * customSizeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size"];
NSArray *sizeValues = [NSArray arrayWithObjects:[NSValue valueWithCGSize:size1], [NSValue valueWithCGSize:size2], [NSValue valueWithCGSize:size3], nil];
[customSizeAnimation setValues:frameValues];
NSArray *times = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0f], [NSNumber numberWithFloat:0.5f], [NSNumber numberWithFloat:1.0f], nil]; 
[customSizeAnimation setKeyTimes:times];
customSizeAnimation.fillMode = kCAFillModeForwards;
customSizeAnimation.removedOnCompletion = NO;
[view.layer addAnimation: customSizeAnimation forKey:@"customSizeAnimation"];

This animation will start at size1, pass through size2 at the midway point in the animation, and end at size3. You can have an arbitrary number of key frames and times for your animation, so you should be able to achieve the effect you desire

EDIT (1/5/2010): Removed kCAAnimationPaced as a calculationMode, which would cause the key times to be ignored. Also, I forgot that frame was a derived property, so you need to animate something like the bounds size instead.

Brad Larson
It sounds great.. I'll try this one..
neha
Brad, I tried it, but it's showing me only one frame located at the top left corner and the initial framesize. I'm passing the frames as three CGRects starting from larger y and then reducing it in each frames. Do I need to add anything more to this code like delegate etc? I added the animation to my UIImageView's layer and added the imageView to self.
neha
They say that if the calculationMode is set to kCAAnimationPaced,the keyTimesarray is ignored.
neha
Sorry about the kCAAnimationPaced, I had copied this out of a different block of code. You're right, it would cause the key times to be ignored.
Brad Larson
Brad, I tried it, it seems that there's something more needed here. It's still showing me my image located at upper left corner with initial frame size.
neha
Sorry, I forgot that a layer's frame is a derived property and can't be animated directly: http://developer.apple.com/mac/library/qa/qa2008/qa1620.html . I've changed the code to reflect this, now animating the layer's bounds size to change the size of the layer. If you wish to also change the position of the layer, you will have to create another CAKeyframeAnimation for the layer's position, and wrap the two animations in a CAAnimationGroup.
Brad Larson
Brad, this' terrible.. Despite providing different sizes it's showing the same size..
neha
I'm not sure what's going wrong in your case, because I use almost this exact same code in one of my applications. Try increasing the duration of the animation (by setting the animation's duration property), and see if it's just the animation running too quickly. Are you adding the animation immediately after the view has been added to its superview? I've sometimes seen animations not execute properly on UIViews that have been just added to the view hierarchy.
Brad Larson
A: 

This' my move function in which I'm trying to change the size of my imageView. If you can point out any error, I'll be really grateful..

-(void)move {

UIImageView *imageViewForAnimation = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ravan.jpg"]];

imageViewForAnimation.alpha = 1.0f;
CGSize size1=CGSizeMake(60,60);
CGSize size2=CGSizeMake(40,40);
CGSize size3=CGSizeMake(20,20);
CAKeyframeAnimation *customFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"frame"];
NSArray *sizeValues = [NSArray arrayWithObjects:[NSValue valueWithCGSize:size1], [NSValue valueWithCGSize:size2], [NSValue valueWithCGSize:size3], nil];
[customFrameAnimation setValues:sizeValues];
customFrameAnimation.duration=10.0;
NSArray *times = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0f], [NSNumber numberWithFloat:0.5f], [NSNumber numberWithFloat:1.0f], nil]; 
[customFrameAnimation setKeyTimes:times];

customFrameAnimation.fillMode = kCAFillModeForwards;
customFrameAnimation.removedOnCompletion = NO;
[imageViewForAnimation.layer addAnimation:customFrameAnimation forKey:@"customFrameAnimation"]; [self.view addSubview:imageViewForAnimation]; }

neha