问题
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:
- First make a crop of image with percent (let`s say 50% fill ) - that is, a bottle filled up to half, from the bottom).
Animate
bigBottleto 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