iOS首页投稿(暂停使用,暂停投稿)UI

核心动画 Core Animation(一、Layer基础)

2017-08-16  本文已影响53人  寻形觅影

核心动画(Core Animation)是iOS和OS X上图形渲染和动画的基础设施,用于为应用程序的视图和其他视觉元素设置动画。核心动画本身不是绘图系统。它是用于在硬件中合成和操纵应用程序内容的基础设施。这种基础设施的核心是层(layer)对象,用于管理和操纵您的内容。一个图层将您的内容捕获到位图中,这些位图可以通过图形硬件轻松操作。在大多数应用程序中,图层用作管理视图内容的一种方式,但也可以根据需要创建独立图层。
 基于layer层的绘图与传统的基于视图的绘图技术有很大的不同。使用基于视图的绘图,对视图本身的更改通常会导致调用视图的drawRect:方法以使用新参数重新绘制内容。但是以这种方式绘制是昂贵的,因为它是使用主线程上的CPU完成的。Core Animation可以通过在硬件中操作缓存的位图来实现相同或相似的效果,从而避免这种代价。

一、关于Layer的几个重要属性及方法

CALayer类中属性和方法有很多,大多数和使用View的方式相同,在此不多赘述,具体可以自行查看CALayer.h文件。下面主要介绍一下比较重要的属性方法。

1、属性:
图例

还有一些常见的属性:如frame, hidden, backgroundColor, cornerRadius, borderWidth, borderColor, shadowColor,shadowOpacity, shadowOffset, shadowRadius, shadowPath 等。

除此之外,核心动画对它所属的CAAnimation和CALayer类扩展了NSKeyValueCoding的协议 --- 必须使用setValue:forKeyPath:valueForKeyPath:方法来设置和获取这些字段,并增加了关键路径对CGPointCGRectCGSize,和CATransform3D类型的支持(表-1)。所以可以直接使用KVC对其 属性 进行赋取值,在这里需要特别注意对transform等结构体来使用keyPath的情形(表-2)

表-1

C类 包装类
CGPoint /CGSize/CGRect/CATransform3D NSValue

表-2

字段路径 包装类及描述
transform.translation NSValue(包含CGSize数据类型) , 在x和y轴上平移的量
transform. translation.x NSNunber , 沿x轴平移
transform. translation.y NSNunber , 沿y轴平移
transform. translation.z NSNunber , 沿z轴平移
transform. scale NSNunber , xyz三个比例因子的平均值
transform. scale.x NSNunber , 沿x轴缩放
transform. scale.y NSNunber , 沿y轴缩放
transform. scale.z NSNunber , 沿z轴缩放
transform. rotation NSNunber , 沿z轴旋转的弧度,与transform. rotation.z相同
transform. rotation.x NSNunber , 沿x轴旋转的弧度
transform. rotation.y NSNunber , 沿y轴旋转的弧度
transform. rotation.z NSNunber , 沿z轴旋转的弧度
*** ***
position NSValue
position.x NSNunber
position.y NSNunber
*** ***
bounds/frame NSValue
bounds.origin 同position
bounds. size NSValue
bounds. size.width NSNumber
bounds. size.height NSNumber

PS-1:基于位置的重力常数:

CA_EXTERN NSString * const kCAGravityCenter
CA_EXTERN NSString * const kCAGravityTop
CA_EXTERN NSString * const kCAGravityBottom
CA_EXTERN NSString * const kCAGravityLeft
CA_EXTERN NSString * const kCAGravityRight
CA_EXTERN NSString * const kCAGravityTopLeft
CA_EXTERN NSString * const kCAGravityTopRight
CA_EXTERN NSString * const kCAGravityBottomLeft
CA_EXTERN NSString * const kCAGravityBottomRight
PS-1

PS-2:基于缩放的重力常数:

CA_EXTERN NSString * const kCAGravityResize
CA_EXTERN NSString * const kCAGravityResizeAspect
CA_EXTERN NSString * const kCAGravityResizeAspectFill
PS-2
2、方法:

代理方法:

所以综以上方法总结layer方法响应链有两种:


关于动画的方法:

示例代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    _blueLayer = [CALayer layer];
    [_blueLayer setValue:(__bridge id)[UIColor blueColor].CGColor forKeyPath:@"backgroundColor"];
    [_blueLayer setValue:[NSValue valueWithCGPoint:CGPointZero] forKeyPath:@"anchorPoint"];
    [_blueLayer setValue:[NSValue valueWithCGRect:CGRectMake(0, 0, 1, 1)] forKeyPath:@"contentsRect"];
    [_blueLayer setValue:(__bridge id)[[UIImage imageNamed:@"boy"] CGImage] forKeyPath:@"contents"];
    [_blueLayer setValue:[NSValue valueWithCGRect:CGRectMake(50, 100, 200, 350)] forKeyPath:@"frame"];
    _blueLayer.delegate = self;
    [self.view.layer addSublayer:_blueLayer];
}
- (void)displayLayer:(CALayer *)layer
{
    if (once) {
        [_blueLayer setValue:[NSValue valueWithCGRect:CGRectMake(0, 0, 1, 0.7)] forKeyPath:@"contentsRect"];
        [_blueLayer setValue:(__bridge id)[[UIImage imageNamed:@"boy"] CGImage] forKeyPath:@"contents"];

    }else{
        [_blueLayer setValue:[NSValue valueWithCGRect:CGRectMake(0, 0, 1, 1)] forKeyPath:@"contentsRect"];
        [_blueLayer setValue:(__bridge id)[[UIImage imageNamed:@"girl"] CGImage] forKeyPath:@"contents"];
    }
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [_blueLayer setValue:kCAGravityResizeAspect forKeyPath:@"contentsGravity"];
    if (once) {
        once = NO;
        [UIView animateWithDuration:10.0 animations:^{
            [_blueLayer setValue:[NSNumber numberWithFloat:100] forKeyPath:@"transform.translation.x"];
            [_blueLayer setValue:[NSNumber numberWithFloat:100] forKeyPath:@"transform.translation.y"];
        }];
    }else{
        [UIView animateWithDuration:10.0 animations:^{
            [_blueLayer setValue:[NSValue valueWithCATransform3D:CATransform3DIdentity] forKeyPath:@"transform"];
        }];
        once = YES;
    }
    [_blueLayer setNeedsDisplay];
}
- (void)dealloc
{
    // 在这里代理一定要置空!否则控制器无法释放
    _blueLayer.delegate = nil;
}
效果图
上一篇 下一篇

猜你喜欢

热点阅读