您的位置:首页 > 移动开发 > IOS开发

iOS CALayer视图图层

2016-04-19 16:46 295 查看
在iOS中都会牵扯到图形转换,动画效果,添加视图,等等的一系列问题,在设计页面,设计图形,添加动画的时候都会使用到这个知识。

简单的说他就是视图的图层,但又不是视图,因为视图可以和用户交互,添加响应事件,添加视图等等,但是CALayer并不可以添加响应事件等等,它只是一个视图的图层,就是这个图片的显示层,展示层,只能够显示内容,比如展示背景颜色,展示图片,设置边框,等等。

UIView上面的rootLayer 发生改变的话 子图层也会发生变化

如果想要改变 button的视图形状边框等,要改变的不止有一个视图 改变的只是其中一个视图的rootLayer 它会显示出显示未被裁切的边框

rootLayer上面没有动画效果

CALayer发生改变 子图层不会跟随发生改变 自带动画效果(当改变属性值的时候) 隐式动画

理解了CALayer之后就可以大致的有一个了解,有个要使用的方向,而且单独对图层做设计修改的时候功能也会比以前多很多,而且当你改变他的图层数值的时候,CALayer是自带隐式动画效果的

接下来看一个图来大概了解下视图的图层关系,下面是我某一个页面的3D图,不得不说Xcode的强大



在左边我们可以详细看到他们的图层是怎么样嵌套的,当你选中一个图层的时候你也可以在上面看到他的所有父视图,或者说在他之前有几层图层,分别是什么,当你对一个视图进行处理的时候,打算处理他的哪一个图层,都很重要。

如果你只处理了一层,比如我为了美观,我想把上图collectionView上面的cell设置了这个属性

cell.layer.cornerRadius = 10;


他就会有一点圆边,让用户感觉上至少比方方正正的好看很多,但是我cell上面还有一层imageView和label,他们都在contentView上面,在这两个属性都为空的时候,cell没有问题,但一旦我设置了图片,而且是填满状态的,显示图片是没有问题,但是你会发现这个cell他又变成方方正正的了,这难免会让人很烦躁,有时候确实会因为各种原因头疼,甚至因此卡住,或者放弃这个效果,白白浪费了一段时间。

感觉有点像打广告的。。所以你要设置的时候要清楚的知道自己要对哪一个图层进行处理,在这里我们只要再给他的ImageView层处理一下layer就可以了

cell.imageView.layer.cornerRadius = 10;
//裁切内容的尺寸
cell.imageView.layer.masksToBounds = YES;


接下来说一下图层的一些属性,可修改的一些属性

bounds 边境范围

position 中心点

zPosition z轴中心点

anchorPoint 锚点 ✮✮✮✮✮

锚点 默认锚点是与中心店重合 锚点的最小值是0,0最大值1,1 默认值是0.5,0.5

当视图 改变的时候 是以锚点为基准去改变

锚点的值与位置

anchorPointZ Z轴锚点

transform 转换形态

frame NO. Animatable 坐标

hidden 隐藏

doubleSided 图层背面是否显示

geometryFlipped 翻转 颠倒

masksToBounds 裁切边境

contents 内容

opaque 不透明度

allowsEdgeAntialiasing 是否使用 变形后的抗锯齿

backgroundColor 背景颜色

borderWidth 边框宽

borderColor 边框颜色

opacity 不透明度

shadowColor 阴影颜色

shadowOpacity 阴影不透明度

rasterizationScale 防止Retina屏幕像素化

shadowOffset 阴影偏移量

shadowRadius 阴影的半径

通过设置这些属性都可以让视图的形态等发生改变,要注意在给CALayer一些属性赋值的时候,他需要的值得类型都是一些特殊类型的值

比如我们之前在给View的transform赋值的时候使用的都是CGAffineTransform类型的,而给CALayer的transform赋值的时候使用使用的是CATransform3D类型的值,包括改变背景颜色也是使用的CGColor,图片是CGImageRef所以使用的时候要注意。

在给他们修改属性的时候,因为CALayer自带隐式动画,所以在触发事件等改变他的属性的时候都会自带动画效果。

在下面要具体说一下CALayer里面的锚点属性,也是动画,视图效果使用最重要的一个属性

大家如果有用过UIView的一些animation的基础动画的时候可能会知道,没用过也没关系,你肯定知道移动视图都是调整视图的center值来做到使视图移动到另外一个位置,设置bounds来放大或缩小一个视图。这里我们不重点说这个。

在这里锚点和视图的center值有点类似,也是通过知道他的中心点,来设置这个中心点,来改变他的位置,不过在这里我们不用中心点了,用的就是锚点来替代了这个点,他可以让视图以任意点为挪动点,比如,一个长长的汽车在行驶,汽车上面的人的位置都是固定不变的,你可以通过改变汽车的中心点来让汽车移动,也可以通过某一个人的位置的改变来改变汽车的位置,比如我现在想让这个汽车通过一个山洞



比如星星是司机,在这里我可以通过这个司机的位置,把司机的X增加一定的数值来让这个车通过这个山洞,和通过改变中心点是一个道理,只不过是这个中心点变了,变成了我们定义的一个锚点。也可以理解成把牛栓在树上,他怎么跑也跑不出这个点,以这个点为移动点来做动作。

理解了这个点的含义,就能做很多事情,比如有些动画就是通过固定锚点来让视图做一些动作



原谅我做不出动图T T,没有美工,在这里我设置图片的旋转就是让他转动半个圆,但是我把它的锚点设置成了他的右下角,所以他会以右下角来转动。

我们简单的写一个实例的layer

我们把CALayer定义成一个全局变量

{
CALayer *layer;

}

layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 100, 100);
layer.backgroundColor = [UIColor colorWithRed:1.000 green:0.607 blue:0.468 alpha:1.000].CGColor;
//在这里注意我们要添加的是一个layer所以要把它添加到我们要修改视图的layer上面
[self.view.layer addSublayer:layer];


然后我们写一个touchBegan的方法

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGFloat width = CGRectGetWidth(layer.bounds)!=100?100:25;
layer.bounds = CGRectMake(0, 0, width, width);

layer.cornerRadius = layer.cornerRadius !=50 ? 50:0;
layer.position = [touch locationInView:self.view];
}


在这里我们也简单写一个锚点的使用,我们继续定义一个CALayer

@property (nonatomic,strong)CALayer *pointLayer;
self.pointLayer.anchorPoint = CGPointMake(0.5 , 0.9);
self.pointLayer.contents = (id)[UIImage
4000
imageNamed:@"要旋转的图片"].CGImage;

- (CALayer *)pointLayer{
if (_pointLayer) {
return _pointLayer;
}
_pointLayer = [CALayer layer];
[self.view.layer addSublayer:_pointLayer];
_pointLayer.bounds = CGRectMake(0, 0, 20, 160);
_pointLayer.position = self.view.center;

return _pointLayer;
}


我们这个图片是一个宽20,高160的图片,我还是放一个图吧,免得被骂。。



嗯。。大概就是这个形状,好的,锚点是以图层的比例来定义的,我定义的是X轴比例0.5,Y比例0.9,也就是说,这个点大概在X是一半,Y是0.9,就是把这个图从上到下分成10份,他在第9份那个位置,大概在如图位置,咳咳。。然后,我们让他来进行一个旋转,正常的旋转应该都是以中心点来旋转,大概画面就像孙悟空耍金箍棒一样,以中心来旋转

我们来设置一个方法通过定时器来调用它

- (void)start{
//    NSCalendar日历的一个类,可以通过它获得年月日  时分秒
//    NSCalendar
//    NSDateComponents  组件    fromDate  获得哪个日期的组件
NSCalendar *calendar = [NSCalendar currentCalendar];
//    @property NSInteger hour;
//    @property NSInteger minute;
//    @property NSInteger second;
NSDateComponents *components = [calendar components:NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:[NSDate date]];

float s = components.second * 6;
//在layer上面添加transform使用的都是CATransform3D
//X  Y  Z是设置绕哪个轴来旋转的   第一个值是旋转的角度
self.pointLayer.transform = CATransform3DMakeRotation(s, 0, 0, 1);
}


然后我们在viewDidLoad添加一个定时器

[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(start) userInfo:nil repeats:YES];


现在他就可以绕点来进行旋转了

具体每个属性都可以自己试一下他的效果,然后发一个有助于理解锚点的demo

锚点demo

最后说一下iOS的核心动画也是通过这个图层来实现的,下次把链接贴上

再贴上一个图层效果的一些处理处理图层特效

我的简书地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios 动画 图形 设计