Search code examples
ioscore-animationuiviewanimation

Show partial content of image using animation


I am working with images in iOS. So when a user presses let's say a button, I want an image to appear to fill up from the bottom to the top.

In order be more precise, imagine a thermometer that is empty and when you press a button the thermometer fills up from the bottom to the top. But I want this with animation.

Do you have any idea how to implement that?

Thanks!


Solution

  • You can easily do it by having a second view acting as a mask over the image view with your image. Then you can apply simple scale transform and animate it revealing the image. Alternatively, you can animate the frame change. Effect will be the same. I'm attaching code for 2 ways of doind this.

    Here is what I achieved in both cases:

    enter image description here

    Code I used for the case I:

    @interface MyViewController ()
    @property(nonatomic, strong) UIImageView *imageView;
    @property(nonatomic, strong) UIView *maskView;
    @end
    
    @implementation MyViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        _imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Image"]];
        _imageView.center = self.view.center;
        _imageView.layer.anchorPoint = CGPointMake(0.5, 0.0);
    
        [self.view addSubview:_imageView];
    
        _maskView = [[UIView alloc] initWithFrame:_imageView.frame];
        _maskView.backgroundColor = [UIColor whiteColor];
        _maskView.center = self.view.center;
        _maskView.layer.anchorPoint = CGPointMake(0.5, 0.0);
    
        [self.view addSubview:_maskView];
    }
    
    - (IBAction)buttonTapped:(id)sender
    {
        [UIView animateWithDuration:1.0f
                         animations:^
        {
            _maskView.transform = CGAffineTransformMakeScale(1.0, 0.0001);
        }];
    }
    
    @end
    

    Code I used for the case II:

    @interface MyViewController ()
    @property(nonatomic, strong) UIImageView *imageView;
    @property(nonatomic, assign) CGFloat height;
    @end
    
    @implementation MyViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        _imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Image"]];
        _imageView.center = self.view.center;
        _imageView.contentMode = UIViewContentModeBottom;
    
        _height = CGRectGetHeight(_imageView.bounds);
    
        CGRect frame = _imageView.frame;
        frame.size.height = 0.00001;
        frame.origin.y += _height;
    
        _imageView.frame = frame;
        _imageView.clipsToBounds = YES;
    
        [self.view addSubview:_imageView];
    }
    
    - (IBAction)buttonTapped:(id)sender
    {
        [UIView animateWithDuration:1.0f
                         animations:^
        {
            CGRect frame = _imageView.frame;
            frame.size.height = _height;
            frame.origin.y -= _height;
    
            _imageView.frame = frame;
        }];
    }
    
    @end
    

    In both cases the end effect was the same.