Core Animation实战四(视觉效果)
2017-10-31 09:27
260 查看
我们知道View中封装了一些动画和显示效果那我们为什么还要操作CALayer层面上呢?
这里有一些
阴影,圆角,带颜色的边框
3D变换
非矩形范围
透明遮罩
多级非线性动画
这篇主要说阴影圆角边框,先看一下Demo效果:
![](https://img-blog.csdn.net/20171031110742346?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWllfRmx5V2F5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
DEMO例子:
放大和缩小过滤的算法属性
/* The filter types to use when rendering the `contents' property of
* the layer. The minification filter is used when to reduce the size
* of image data, the magnification filter to increase the size of
* image data. Currently the allowed values are `nearest' and `linear'.
* Both properties default to `linear'. */
@property(copy)
NSString *minificationFilter;
@property(copy)
NSString *magnificationFilter;
/* The bias factor added when determining which levels of detail to use
* when minifying using trilinear filtering. The default value is 0.
* Animatable. */
@property float minificationFilterBias;
算法如下
/** Contents filter names. **/
CA_EXTERN NSString *
const kCAFilterNearest
CA_AVAILABLE_STARTING (10.5,
2.0,
9.0, 2.0);
CA_EXTERN NSString *
const kCAFilterLinear
CA_AVAILABLE_STARTING (10.5,
2.0,
9.0, 2.0);
/* Trilinear minification filter. Enables mipmap generation. Some
* renderers may ignore this, or impose additional restrictions, such
* as source images requiring power-of-two dimensions. */
CA_EXTERN NSString *
const kCAFilterTrilinear
CA_AVAILABLE_STARTING (10.6,
3.0,
9.0, 2.0);
默认的过滤器都是kCAFilterLinear,这个过滤器采用双线性滤波算法,它在大多数情况下都表现良好。双线性滤波算法通过对多个像素取样最终生成新的值,得到一个平滑的表现不错的拉伸。但是当放大倍数比较大的时候图片就模糊不清了。
kCAFilterTrilinear和kCAFilterLinear非常相似,大部分情况下二者都看不出来有什么差别。但是,较双线性滤波算法而言,三线性滤波算法存储了多个大小情况下的图片(也叫多重贴图),并三维取样,同时结合大图和小图的存储进而得到最后的结果
kCAFilterNearest是一种比较武断的方法。从名字不难看出,这个算法(也叫最近过滤)就是取样最近的单像素点而不管其他的颜色。这样做非常快,也不会使图片模糊。但是,最明显的效果就是,会使得压缩图片更糟,图片放大之后也显得块状或是马赛克严重。
DEMO如下:
//
// TensileFilterViewController.m
// LayerStudyDemo
//
// Created by apple on 2017/9/28.
// Copyright © 2017年 ZY. All rights reserved.
//
#import "TensileFilterViewController.h"
@interface TensileFilterViewController ()
@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *LedViews1;
@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *LedView2;
@property (nonatomic, weak) NSTimer *timer;
@end
@implementation TensileFilterViewController
{
NSArray * array;
}
- (void)viewDidLoad {
[super viewDidLoad];
array = @[self.LedViews1,self.LedView2];
UIImage *digits = [UIImage imageNamed:@"led.png"];
for (int i=0; i<array.count; i++) {
for (UIView *view in array[i]) {
//set contents
view.layer.contents = (__bridge id)digits.CGImage;
view.layer.contentsRect = CGRectMake(0, 0, 0.1, 1.0);
view.layer.contentsGravity = kCAGravityResizeAspect;
if (i==1) {
view.layer.minificationFilter = kCAFilterNearest;
}
}
}
//start timer
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick) userInfo:nil repeats:YES];
}
- (void)tick
{
//convert time to hours, minutes and seconds
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierRepublicOfChina];
NSUInteger units = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
for (int i=0; i<array.count; i++) {
//set hours
[self setDigit:components.hour / 10 forView:array[i][0]];
[self setDigit:components.hour % 10 forView:array[i][1]];
//set minutes
[self setDigit:components.minute / 10 forView:array[i][2]];
[self setDigit:components.minute % 10 forView:array[i][3]];
//set seconds
[self setDigit:components.second / 10 forView:array[i][4]];
[self setDigit:components.second % 10 forView:array[i][5]];
}
}
- (void)setDigit:(NSInteger)digit forView:(UIView *)view
{
//adjust contentsRect to select correct digit
view.layer.contentsRect = CGRectMake(digit * 0.1, 0, 0.1, 1.0);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
DEMO地址
这里有一些
UIView没有暴露出来的CALayer的功能:
阴影,圆角,带颜色的边框
3D变换
非矩形范围
透明遮罩
多级非线性动画
这篇主要说阴影圆角边框,先看一下Demo效果:
DEMO例子:
// // VisualEffectViewController.m // LayerStudyDemo // // Created by apple on 2017/9/26. // Copyright © 2017年 ZY. All rights reserved. // #import "VisualEffectViewController.h" @interface VisualEffectViewController () @property (weak, nonatomic) IBOutlet UIView *View1; @property (strong, nonatomic) IBOutlet UIView *View2; @property (weak, nonatomic) IBOutlet UIView *shadowView; @property (weak, nonatomic) IBOutlet UIImageView *timeImage; @end @implementation VisualEffectViewController - (void)viewDidLoad { [super viewDidLoad]; [self layerCornerRadiusAndWidth]; [self shadowEffect]; [self shadowPath]; } //layer的圆角,裁剪,边框。 -(void)layerCornerRadiusAndWidth{ //圆角弧度 self.View1.layer.cornerRadius = 30; 4000 //是否边框外绘制 self.View1.layer.masksToBounds = YES; //边框颜色 self.View1.layer.borderColor = [UIColor blackColor].CGColor; //边框宽度 self.View1.layer.borderWidth = 3; } //阴影效果 -(void)shadowEffect{ //阴影透明度 self.shadowView.layer.shadowOpacity = 0.8; //阴影颜色 self.shadowView.layer.shadowColor = [self getColorFromRed:0 Green:1 Blue:0 Alpha:1]; // shadowOffset属性控制着阴影的方向和距离。它是一个CGSize的值,宽度控制这阴影横向的位移,高度控制着纵向的位移。 self.shadowView.layer.shadowOffset = CGSizeMake(1, 1); //shadowRadius属性控制着阴影的模糊度,当它的值是0的时候,阴影就和视图一样有一个非常确定的边界线。当值越来越大的时候,边界线看上去就会越来越模糊和自然。苹果自家的应用设计更偏向于自然的阴影,所以一个非零值再合适不过了。 self.shadowView.layer.shadowRadius = 100; } //CGColorRef -(CGColorRef) getColorFromRed:(int)red Green:(int)green Blue:(int)blue Alpha:(int)alpha { // RGBA 色彩 (显示3色) CGColorSpaceRef rgbSapceRef = CGColorSpaceCreateDeviceRGB();// RGB 色彩空间 CGFloat rgbComponents[] = {red, green, blue, 1};// RGBA 颜色组件 CGColorRef rgbColorRef = CGColorCreate(rgbSapceRef, rgbComponents);// 一般创建 CGColor return rgbColorRef; } //阴影路径 -(void)shadowPath{ self.timeImage.layer.shadowOpacity = 0.5; //create a square shadow // CGMutablePathRef squarePath = CGPathCreateMutable(); // CGPathAddRect(squarePath, NULL, self.timeImage.bounds); // self.timeImage.layer.shadowPath = squarePath; // CGPathRelease(squarePath); //create a circular shadow CGMutablePathRef circlePath = CGPathCreateMutable(); CGPathAddEllipseInRect(circlePath, NULL, self.timeImage.bounds); self.timeImage.layer.shadowPath = circlePath; CGPathRelease(circlePath); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
图层蒙版
// // MaskLayerViewController.m // LayerStudyDemo // // Created by apple on 2017/9/27. // Copyright © 2017年 ZY. All rights reserved. // #import "MaskLayerViewController.h" @interface MaskLayerViewController () @property (weak, nonatomic) IBOutlet UIImageView *maskImage; @end @implementation MaskLayerViewController - (void)viewDidLoad { [super viewDidLoad]; [self maskView]; } //maskLayer -(void)maskView{ CALayer * maskLayer = [CALayer layer]; maskLayer.frame = self.maskImage.bounds; UIImage * image = [UIImage imageNamed:@"time.png"]; maskLayer.contents = (__bridge id _Nullable)(image.CGImage); self.maskImage.layer.mask = maskLayer; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
拉伸过滤
放大和缩小过滤的算法属性/* The filter types to use when rendering the `contents' property of
* the layer. The minification filter is used when to reduce the size
* of image data, the magnification filter to increase the size of
* image data. Currently the allowed values are `nearest' and `linear'.
* Both properties default to `linear'. */
@property(copy)
NSString *minificationFilter;
@property(copy)
NSString *magnificationFilter;
/* The bias factor added when determining which levels of detail to use
* when minifying using trilinear filtering. The default value is 0.
* Animatable. */
@property float minificationFilterBias;
算法如下
/** Contents filter names. **/
CA_EXTERN NSString *
const kCAFilterNearest
CA_AVAILABLE_STARTING (10.5,
2.0,
9.0, 2.0);
CA_EXTERN NSString *
const kCAFilterLinear
CA_AVAILABLE_STARTING (10.5,
2.0,
9.0, 2.0);
/* Trilinear minification filter. Enables mipmap generation. Some
* renderers may ignore this, or impose additional restrictions, such
* as source images requiring power-of-two dimensions. */
CA_EXTERN NSString *
const kCAFilterTrilinear
CA_AVAILABLE_STARTING (10.6,
3.0,
9.0, 2.0);
默认的过滤器都是kCAFilterLinear,这个过滤器采用双线性滤波算法,它在大多数情况下都表现良好。双线性滤波算法通过对多个像素取样最终生成新的值,得到一个平滑的表现不错的拉伸。但是当放大倍数比较大的时候图片就模糊不清了。
kCAFilterTrilinear和kCAFilterLinear非常相似,大部分情况下二者都看不出来有什么差别。但是,较双线性滤波算法而言,三线性滤波算法存储了多个大小情况下的图片(也叫多重贴图),并三维取样,同时结合大图和小图的存储进而得到最后的结果
kCAFilterNearest是一种比较武断的方法。从名字不难看出,这个算法(也叫最近过滤)就是取样最近的单像素点而不管其他的颜色。这样做非常快,也不会使图片模糊。但是,最明显的效果就是,会使得压缩图片更糟,图片放大之后也显得块状或是马赛克严重。
DEMO如下:
//
// TensileFilterViewController.m
// LayerStudyDemo
//
// Created by apple on 2017/9/28.
// Copyright © 2017年 ZY. All rights reserved.
//
#import "TensileFilterViewController.h"
@interface TensileFilterViewController ()
@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *LedViews1;
@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *LedView2;
@property (nonatomic, weak) NSTimer *timer;
@end
@implementation TensileFilterViewController
{
NSArray * array;
}
- (void)viewDidLoad {
[super viewDidLoad];
array = @[self.LedViews1,self.LedView2];
UIImage *digits = [UIImage imageNamed:@"led.png"];
for (int i=0; i<array.count; i++) {
for (UIView *view in array[i]) {
//set contents
view.layer.contents = (__bridge id)digits.CGImage;
view.layer.contentsRect = CGRectMake(0, 0, 0.1, 1.0);
view.layer.contentsGravity = kCAGravityResizeAspect;
if (i==1) {
view.layer.minificationFilter = kCAFilterNearest;
}
}
}
//start timer
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick) userInfo:nil repeats:YES];
}
- (void)tick
{
//convert time to hours, minutes and seconds
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierRepublicOfChina];
NSUInteger units = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
for (int i=0; i<array.count; i++) {
//set hours
[self setDigit:components.hour / 10 forView:array[i][0]];
[self setDigit:components.hour % 10 forView:array[i][1]];
//set minutes
[self setDigit:components.minute / 10 forView:array[i][2]];
[self setDigit:components.minute % 10 forView:array[i][3]];
//set seconds
[self setDigit:components.second / 10 forView:array[i][4]];
[self setDigit:components.second % 10 forView:array[i][5]];
}
}
- (void)setDigit:(NSInteger)digit forView:(UIView *)view
{
//adjust contentsRect to select correct digit
view.layer.contentsRect = CGRectMake(digit * 0.1, 0, 0.1, 1.0);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
DEMO地址
相关文章推荐
- iOS Core Animation--视觉效果
- Core Animation - 视觉效果<一>
- Core Animation - 视觉效果<三>
- Core Animation - 视觉效果<二>
- iOS-Core Animation 核心动画高级编程/4-视觉效果
- 为灾区祈福 Flash制作地震视觉效果
- 【PS3】二之国 白色圣灰的女王 日本制造的视觉效果
- [iOS Animation]-CALayer 视觉效果
- 收集android上开源的酷炫的交互动画和视觉效果:Interactive-animation
- 【实战】对Torque引擎逼真水效果的升级和改造-技术篇(water fix in Torque -- How to do)
- Android 手势检测实战 打造支持缩放平移的图片预览效果(下)
- 提升应用视觉Android效果的10个UI技巧
- iOS TableView滚动时的视觉差效果
- ViewSwitcher和TextSwithcher打造不一样的视觉效果
- JavaScript实战(带收放动画效果的导航菜单)
- Core Animation之多种动画效果
- 网页设计如何获得好的视觉效果
- 如何在.NET程序中启动xp的视觉效果
- 视觉滚动效果和图形化在网页中的呈现
- ios开发——使用CALayer和Core Animation做动画效果