Search code examples
iphonecocoa-touchuiviewcore-animationuiimage

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.


Solution

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