Fill percent of UIImageView from full UIImage with animation

做~自己de王妃 提交于 2019-12-10 11:56:43

问题


I have an UIImageView named bigBottle:

bigBottle.image =  [UIImage imageNamed:@"fullBootle.png"];

fullBootle.png is a bottle filled up to 100%.

I need two steps:

  1. First make a crop of image with percent (let`s say 50% fill ) - that is, a bottle filled up to half, from the bottom).
  2. Animate bigBottle to creeate a filling effect from down of the bottle to 50% fill. My code is bellow:

    CGRect captureRect = CGRectMake(0,22,18,72);
    UIImage *captureImg;
    UIGraphicsBeginImageContext(captureRect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [self.bigBottle.layer renderInContext:context];
    captureImg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    self.bigBottle.image = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(captureImg.CGImage,
    captureRect)];
    CGRect captureRect1 = CGRectMake(0,37,18,72);
    self.bigBottle.frame=CGRectMake(45, 174,18,1);
    CGRect newFrameOfMyView1 = CGRectMake(45,129, 18, 45);
    [UIView animateWithDuration:3.0f
        animations:^{
            self.bigBottle.frame = newFrameOfMyView1;
        }
        completion:^(BOOL finished){
            NSLog( @"done bottle: 1" );
    }];
    

It is another way to make this animation of filling the bottle more simple, and more memory efficient? I have dozens of bottles to fill random with percent (let`s say bottle80 is 20% filled up) and to not have blurred resulting images ?


回答1:


Here is my simple implementation to your question. Create a new subclass of CALayer and implement a dynamic property called percent and then animate it as,

ImageLayer.h

#import <QuartzCore/QuartzCore.h>

@interface ImageLayer : CALayer
  @property (nonatomic,assign )float percent;
  @property (nonatomic, strong) NSString *imageName;
@end

ImageLayer.m

#import "ImageLayer.h"

@implementation ImageLayer
@dynamic percent;


+ (BOOL)needsDisplayForKey:(NSString *)key{
  if([key isEqualToString:@"percent"]){
    return YES;
  }else
    return [super needsDisplayForKey:key];
}


- (void)drawInContext:(CGContextRef)ctx{
  UIGraphicsPushContext(ctx);
  UIImage *image = [UIImage imageNamed:@"Bottle.jpg"];
  [image drawInRect:self.bounds];
  float heightToBeCovered =  self.percent * CGRectGetHeight(self.bounds);
  float verticalYPosition = CGRectGetHeight(self.bounds) - heightToBeCovered;
  UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, verticalYPosition, CGRectGetWidth(self.bounds), heightToBeCovered )];
  [[UIColor blackColor] setFill];
  [path fill];
  UIGraphicsPopContext();
}

@end

ViewController.m

@implementation ViewController

- (void)viewDidLoad
{
  [super viewDidLoad];
  ImageLayer *imageLayer = [ImageLayer layer];
  imageLayer.position = self.view.center;
  imageLayer.frame = self.view.bounds;
  [self.view.layer addSublayer:imageLayer];
  CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"percent"];
  [animation setFromValue:@1];
  [animation setToValue:@0];

  [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
  [animation setDuration:10.0];
  [imageLayer addAnimation:animation forKey:@"imageAnimation"];


}

@end



回答2:


No, I just make this fill-up with simple animation:

self.bigBottle.frame =CGRectMake(self.bigBottle.frame.origin.x,self.bigBottle.frame.origin.y + self.bigBottle.frame.size.height,18,0); /*so the height is 0 on start*/
[self.bigBottle setClipsToBounds:YES]; //so image will be bounds to UIImageView bounds
[UIView animateWithDuration:2.0f animations:^{ self.bigBottle.frame =CGRectMake(self.bigBottle.frame.origin.x,self.bigBottle.frame.origin.y -43 ,18,self.bigBottle.frame.size.height+43); //where 43 is a value I generate random 


来源:https://stackoverflow.com/questions/21973908/fill-percent-of-uiimageview-from-full-uiimage-with-animation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!