(一)CALayer
(1)CA就是CoreAnimation核心动画的意思。在iOS中,所有的看得见的控件都是UIView,但是UIView之所以能显示在屏幕上,全是因为内部有一个图层。当你创建UIView,UIView会自动创建一个图层(CALayer对象)。通过UIView的layer属性可以访问这个层。当UIView要显示的时候,会调用drawRect进行绘制。把所有内容绘制到图层上,然后把图层拷贝到屏幕上,于是就完成了UIView的显示。所以说UIView本身不具备显示。显示是图层干的事情。
(2)通过调用CALayer可以方便的调整UIView的一些外观。例如阴影,圆角大小,边框宽度,颜色等等。还可以给图层添加动画实现炫酷效果。
(3)如果要触发事件,需要用到UIView,因为CALayer不能触发事件。
(4)CALayer是定义在QuartzCore中的。
// --- layer的基本属性// 设置layer边框testView.layer.borderWidth = 10; // 边框的宽度testView.layer.borderColor = [UIColor whiteColor].CGColor; // 边框的颜色// 设置layer阴影testView.layer.shadowColor = [UIColor blueColor].CGColor; // 颜色testView.layer.shadowOffset = CGSizeMake(20, 20); // 偏移量testView.layer.shadowOpacity = 0.7; // 透明度 默认为0,所以不会显示.testView.layer.shadowRadius = 10; //圆角// 设置layer圆角testView.layer.cornerRadius = 50; // 设置layer的圆角半径testView.layer.masksToBounds = YES; // 裁剪 设置头像的时候 记得加上// bounds 大小// testView.layer.bounds = CGRectMake(0, 0, 200, 200);// position 位置// testView.layer.position = CGPointMake(0, 0); // 默认的位置是view得center// 设置内容 (__bridge id)把cg转化成idtestView.layer.contents = (__bridge id)([UIImage imageNamed:@"haoyuexing"].CGImage); // 图片
(3)layer的隐式动画。自己更改frame的时候自动有动画,不需要UIView animation执行动画。UIView这种叫做属性动画,目的就是动画。隐士动画还有一个概念叫做可动画属性,只有可动画属性的才有隐式动画。
- (void)viewDidLoad { [super viewDidLoad]; CALayer *layer = [CALayer new]; layer.frame = CGRectMake(100, 100, 100, 100); layer.backgroundColor = [UIColor redColor].CGColor; layer.cornerRadius = 50; self.mylayer = layer; [self.view.layer addSublayer:layer];}- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event { self.mylayer.position = CGPointMake(300, 300);}
显示Aimatable就是隐式属性。但是这个动画,直接layer是没有的。只有手动创建的layer才有动画。
禁止隐式动画:
// 禁止隐式动画[CATransaction begin];[CATransaction setDisableActions:YES];[CATransaction commit];// 可动画属性 = 直接设置这个属性 就能够出现隐式动画// 控件的根layer式没有可动画属性的 也就是说 直接改变控件的layer的属性 是不能够有隐式动画的// Animatable 可动画属性的标记
(4)layer的transform:
4.1旋转:
// 旋转 x y z 分别是三个轴,想要在哪个轴旋转 就赋值为1 self.mylayer.transform = CATransform3DRotate(self.mylayer.transform, M_PI_4, 1, 1, 1);
4.2缩放: Z轴没效果
// 缩放 x y z 分别是三个轴的缩放比例 self.mylayer.transform = CATransform3DScale(self.mylayer.transform, 0.5, 1, 1);
4.3平移:Z轴没效果
// 平移 x y z 分别是三个轴的平移量,z依然没用 self.mylayer.transform = CATransform3DTranslate(self.mylayer.transform, 100, 100, 100);
(5)做一个时钟
5.1获取系统当前时间:
方法1:NSDate获取系统时间。
// 1 ---------- NSDate NSDate* date = [NSDate date]; NSDateFormatter* formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @"ss"; CGFloat second = [[formatter stringFromDate:date] floatValue]; // ---------- NSDate
方法2:日历获取时间一部分。
// 2 ---------- NSCalendar // 获取当前日历对象 NSCalendar* cal = [NSCalendar currentCalendar]; // 获取其中某一部分的时间 CGFloat second = [cal component:NSCalendarUnitSecond fromDate:date]; // ---------- NSCalendar
5.2定时器:
方法1:NSTimer,但是时机可能不对。
// 添加定时器 每一秒调用 time 的方法 // [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(time) userInfo:nil repeats:YES];
方法2:CADisplayLink:一秒执行60次,以屏幕刷新频率触发为参数。也是一个定时器。
// 创建一个CADisplayLink对象 CADisplayLink* link = [CADisplayLink displayLinkWithTarget:self selector:@selector(time)]; // 把 link 添加到 主消息循环当中 [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
实现:
- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 创建一个CALayer CALayer* clock = [[CALayer alloc] init]; clock.frame = CGRectMake(100, 100, 200, 200); clock.contents = (__bridge id)([UIImage imageNamed:@"clock"].CGImage); // 设置内容 clock.cornerRadius = 100; // 设置圆角 clock.masksToBounds = YES; // 设置裁剪 CALayer* second = [[CALayer alloc] init]; self.second = second; second.position = clock.position; // 设置位置 second.bounds = CGRectMake(0, 0, 2, 80); // 设置大小 second.backgroundColor = [UIColor redColor].CGColor; // 颜色 // 锚点 定位点 second.anchorPoint = CGPointMake(0.5, 0.8); // 设置锚点!!!!!!!!! // 添加到控制器view的layer上去 [self.view.layer addSublayer:clock]; [self.view.layer addSublayer:second]; // [self time]; // 添加定时器 每一秒调用 time 的方法 // [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(time) userInfo:nil repeats:YES]; // 创建一个CADisplayLink对象 CADisplayLink* link = [CADisplayLink displayLinkWithTarget:self selector:@selector(time)]; // 把 link 添加到 主消息循环当中 [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];}- (void)time{// // 1 ---------- NSDate NSDate* date = [NSDate date];// NSDateFormatter* formatter = [[NSDateFormatter alloc] init];// formatter.dateFormat = @"ss";// CGFloat second = [[formatter stringFromDate:date] floatValue];// // ---------- NSDate // 2 ---------- NSCalendar // 获取当前日历对象 NSCalendar* cal = [NSCalendar currentCalendar]; // 获取其中某一部分的时间 CGFloat second = [cal component:NSCalendarUnitSecond fromDate:date]; // ---------- NSCalendar CGFloat angle = 2 * M_PI / 60 * second; // 每次旋转360/60度 // self.second.affineTransform = CGAffineTransformRotate(self.second.affineTransform, angle); self.second.affineTransform = CGAffineTransformMakeRotation(angle);}