使用图像创建自定义仪表 Objective C
Create a custom gauge with an image Objective C
我想为我的应用程序创建一个自定义仪表,它将显示一个心形,动画从下到上填充。
我不明白如何创建这种效果。
鉴于问题的模糊性,众多解决方案之一是使用 Core Animation。 Apple 官方文档是 here.
让我们概述三个步骤:
- 概念步骤定义您将使用的图层(概念上)或蒙版,并创建将导入其中的图像
- 定义步骤定义你的
CABasicAnimation
并对层进行编程
- 动画步骤应用您的修改
让我们来看看细节。
概念步骤
假设您选择三层:
- 背景
- 空心形(例如,漂亮的银色线条,或者什么都没有)
- 填充的心形(例如,漂亮的 gem 心形、果冻形或苹果红皮形切工...询问您的艺术家)
此时,如果您正在为 iPad 构建,您的美工人员已经为您提供了 6 个文件。让我们假设以下名称和类型。
| Name | Type|
|:-----:|:––––:|
|background.jpg| background picture for iPad Mini |
|background@2x.jpg|background picture for iPad Retina and up |
|heartenclosure.png| heart border picture for iPad Mini |
|heartenclosure@2x.png|heart border picture for iPad Retina and up |
|heartbody.png| heart contents picture for iPad Mini |
|heartbody@2x.png|heart contents picture for iPad Retina and up |
将这些作为 JPG/PNG 文件后,将它们导入 Xcode。注意 Retina(和 iPhone 6+),双倍和三倍尺寸。您将把它们拖放到名为 Images.xcassets
的文件中,该文件(几乎)是您的 "image store".
定义步骤
计划是让背景是静态的,每当 jauge 更新时,心形内容从当前高度动画到新高度,心形边框作为顶层。
让我们构建背景图像:
UIImage* backgroundImg = [UIImage imageNamed:@"background"];
并且相同的代码将创建顶部图片:
UIImage* heartshapeImg = [UIImage imageNamed:@"heartenclosure"];
iOS 足够聪明 select 正确的图像,您不必传递 JPG 或 @2x 信息。默认情况下,添加到显示的图像的 z-index 为 "latest on top".
图片建好后,在我的iPhone上看起来像this(向原画师致歉)。
我们要做的是创建三个 CALayers
并将它们添加为 UIView
的图层子图层,这只是众多可能性中的一种。
为了我自己的缘故,我做了一个 heart shape based on a nice heart found with Google。在你的项目中,你会想要我之前建议的真正的艺术 ;)
构建层的代码进入- (void) viewDidAppear:(BOOL)animated
(因为此时,框架已经设置好)。
注意在心层上设置的名称,这将允许我们对其进行动画处理。
UIImage* backgroundImg = [UIImage imageNamed:@"background"];
UIImage* heartImage = [UIImage imageNamed:@"Coeur"];
UIImage* heartShapeImage = [UIImage imageNamed:@"Coeurshape"];
CALayer* backgroundLayer = [CALayer layer];
backgroundLayer.contentsGravity = kCAGravityResizeAspect;
backgroundLayer.opacity = 1;
backgroundLayer.opaque = YES;
backgroundLayer.hidden = NO;
backgroundLayer.cornerRadius = 20.0;
backgroundLayer.frame = CGRectInset(self.view.layer.frame, 20, 20);
backgroundLayer.backgroundColor = [[UIColor colorWithRed:1.1 green:1 blue:0 alpha:1.0]CGColor];
backgroundLayer.contents = (__bridge id) backgroundImg.CGImage;
backgroundLayer.contentsScale = [[UIScreen mainScreen] scale];
[self.view.layer addSublayer:backgroundLayer ];
CALayer* heartLayer =[CALayer layer];
heartLayer.contentsGravity = kCAGravityResizeAspect;
heartLayer.shadowOffset = CGSizeMake(0, 3);
heartLayer.shadowRadius = 5.0;
heartLayer.shadowColor = [UIColor blackColor].CGColor;
heartLayer.shadowOpacity = 0.8;
heartLayer.frame = CGRectInset(self.view.layer.frame, 80, 200);
heartLayer.contents = (__bridge id) heartImage.CGImage;
heartLayer.contentsScale = [[UIScreen mainScreen] scale];
[heartLayer setName:@"heartLayer"];
[self.view.layer addSublayer:heartLayer];
CALayer* heartShapeLayer =[CALayer layer];
heartShapeLayer.contentsGravity = kCAGravityResizeAspect;
heartShapeLayer.frame = heartLayer.frame;
heartShapeLayer.contents = (__bridge id)(heartShapeImage.CGImage);
heartShapeLayer.contentsScale = [[UIScreen mainScreen] scale];
[self.view.layer addSublayer:heartShapeLayer];
* 动画步长*
通过使用 CABasicAnimation
更改 heartLayer 的边界,启用蒙版:heartLayer.masksToBounds = YES;
然后您可以显示您想要的心的数量。
为了访问您的子图层,您需要使用它的名称。
这个子例程可以解决问题:
- (CALayer *)findLayerByName:(NSString*) layerTagName inLayer:(CALayer*) layer{
for (CALayer *layer in [layer sublayers]) {
if ([[layer name] isEqualToString:layerTagName]) {
return layer;
}
}
return nil;
}
请注意,根据我之前的评论,使用 Swift 是一个不错的选择。 Ray Wenderlich 的网站上有一篇关于 UIView animations in Swift 的好文章。
我想为我的应用程序创建一个自定义仪表,它将显示一个心形,动画从下到上填充。
我不明白如何创建这种效果。
鉴于问题的模糊性,众多解决方案之一是使用 Core Animation。 Apple 官方文档是 here.
让我们概述三个步骤:
- 概念步骤定义您将使用的图层(概念上)或蒙版,并创建将导入其中的图像
- 定义步骤定义你的
CABasicAnimation
并对层进行编程 - 动画步骤应用您的修改
让我们来看看细节。
概念步骤
假设您选择三层:
- 背景
- 空心形(例如,漂亮的银色线条,或者什么都没有)
- 填充的心形(例如,漂亮的 gem 心形、果冻形或苹果红皮形切工...询问您的艺术家)
此时,如果您正在为 iPad 构建,您的美工人员已经为您提供了 6 个文件。让我们假设以下名称和类型。
| Name | Type|
|:-----:|:––––:|
|background.jpg| background picture for iPad Mini |
|background@2x.jpg|background picture for iPad Retina and up |
|heartenclosure.png| heart border picture for iPad Mini |
|heartenclosure@2x.png|heart border picture for iPad Retina and up |
|heartbody.png| heart contents picture for iPad Mini |
|heartbody@2x.png|heart contents picture for iPad Retina and up |
将这些作为 JPG/PNG 文件后,将它们导入 Xcode。注意 Retina(和 iPhone 6+),双倍和三倍尺寸。您将把它们拖放到名为 Images.xcassets
的文件中,该文件(几乎)是您的 "image store".
定义步骤
计划是让背景是静态的,每当 jauge 更新时,心形内容从当前高度动画到新高度,心形边框作为顶层。
让我们构建背景图像:
UIImage* backgroundImg = [UIImage imageNamed:@"background"];
并且相同的代码将创建顶部图片:
UIImage* heartshapeImg = [UIImage imageNamed:@"heartenclosure"];
iOS 足够聪明 select 正确的图像,您不必传递 JPG 或 @2x 信息。默认情况下,添加到显示的图像的 z-index 为 "latest on top".
图片建好后,在我的iPhone上看起来像this(向原画师致歉)。
我们要做的是创建三个 CALayers
并将它们添加为 UIView
的图层子图层,这只是众多可能性中的一种。
为了我自己的缘故,我做了一个 heart shape based on a nice heart found with Google。在你的项目中,你会想要我之前建议的真正的艺术 ;)
构建层的代码进入- (void) viewDidAppear:(BOOL)animated
(因为此时,框架已经设置好)。
注意在心层上设置的名称,这将允许我们对其进行动画处理。
UIImage* backgroundImg = [UIImage imageNamed:@"background"]; UIImage* heartImage = [UIImage imageNamed:@"Coeur"]; UIImage* heartShapeImage = [UIImage imageNamed:@"Coeurshape"];
CALayer* backgroundLayer = [CALayer layer];
backgroundLayer.contentsGravity = kCAGravityResizeAspect;
backgroundLayer.opacity = 1;
backgroundLayer.opaque = YES;
backgroundLayer.hidden = NO;
backgroundLayer.cornerRadius = 20.0;
backgroundLayer.frame = CGRectInset(self.view.layer.frame, 20, 20);
backgroundLayer.backgroundColor = [[UIColor colorWithRed:1.1 green:1 blue:0 alpha:1.0]CGColor];
backgroundLayer.contents = (__bridge id) backgroundImg.CGImage;
backgroundLayer.contentsScale = [[UIScreen mainScreen] scale];
[self.view.layer addSublayer:backgroundLayer ];
CALayer* heartLayer =[CALayer layer];
heartLayer.contentsGravity = kCAGravityResizeAspect;
heartLayer.shadowOffset = CGSizeMake(0, 3);
heartLayer.shadowRadius = 5.0;
heartLayer.shadowColor = [UIColor blackColor].CGColor;
heartLayer.shadowOpacity = 0.8;
heartLayer.frame = CGRectInset(self.view.layer.frame, 80, 200);
heartLayer.contents = (__bridge id) heartImage.CGImage;
heartLayer.contentsScale = [[UIScreen mainScreen] scale];
[heartLayer setName:@"heartLayer"];
[self.view.layer addSublayer:heartLayer];
CALayer* heartShapeLayer =[CALayer layer];
heartShapeLayer.contentsGravity = kCAGravityResizeAspect;
heartShapeLayer.frame = heartLayer.frame;
heartShapeLayer.contents = (__bridge id)(heartShapeImage.CGImage);
heartShapeLayer.contentsScale = [[UIScreen mainScreen] scale];
[self.view.layer addSublayer:heartShapeLayer];
* 动画步长*
通过使用 CABasicAnimation
更改 heartLayer 的边界,启用蒙版:heartLayer.masksToBounds = YES;
然后您可以显示您想要的心的数量。
为了访问您的子图层,您需要使用它的名称。 这个子例程可以解决问题:
- (CALayer *)findLayerByName:(NSString*) layerTagName inLayer:(CALayer*) layer{
for (CALayer *layer in [layer sublayers]) {
if ([[layer name] isEqualToString:layerTagName]) {
return layer;
}
}
return nil;
}
请注意,根据我之前的评论,使用 Swift 是一个不错的选择。 Ray Wenderlich 的网站上有一篇关于 UIView animations in Swift 的好文章。