1.图形上下文Graphics context,是一个CGContextRef类型的数据。它可以:
①保存绘图信息、绘图状态等
②决定绘图的输出目标,以为绘制到什么地方去。绘制目标可以是PDF文件或当前窗口等。
画弧形时的坐标如下(下边写错了,“正方形”应为“正方向”):
添加弧形时函数的参数如下:
所以要想画如下的弧形,那么可以用
-(void)drawHalfArc{
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 参数含义
// x,y为圆心,radius为半径
// startAngle为起始角度,endAngle为终点角度
// clockwise为绘制方向,只有两个值,0为顺时针,1为逆时针
CGContextAddArc(ctx, 100, 350, 80, -M_PI_2, M_PI_2*1.4, 0);
CGContextStrokePath(ctx);
}
设置线条的颜色,最简单的可用类似
[[UIColor brownColor] set];
而不用管线是空心的还是实心。
2.CALayer的属性position和anchorPoint
这二者是相对于不同的坐标系的,position是相对于superLayer,anchorPoint是相对于layer的。
@property CGPoint point
决定了layer在父层中的位置,以父层的左上角为原点(0,0);
@property CGPoint anchorPoint
为锚点,它以自己的左上角为原点(0,0),x、y取值范围都为0~1,默认值为(0.5,0.5)。意为即使layer长宽都为100,但它的锚点范围仍为0~1。
layer能以锚点为基准点旋转或是移动,做动画时能用到。
设置layer时,
layer.frame = CGRectMake(110, 110, 100, 100);
CGRectMake前两项参数是没有作用的,只能以position来决定。
以一段代码为例
//没设置anchorPoint,为默认值
-(void)setUpBackground{
CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor redColor].CGColor;
layer.frame = CGRectMake(110, 110, 100, 100);
layer.position = CGPointZero;
[self.view.layer addSublayer:layer];
}
效果为
若设置anchorPoint
-(void)setUpBackground{
CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor redColor].CGColor;
layer.frame = CGRectMake(110, 110, 100, 100);
layer.position = CGPointZero;
layer.anchorPoint = CGPointZero;
[self.view.layer addSublayer:layer];
}
则效果变为:
由上可以得出,position在superLayer中的位置与anchorPoint在layer中的位置是重叠的。
3.UIView的旋转默认是围绕view.center或view.layer.anchorPoint旋转。
4.对于NSNumber对象,有两种写法
①工厂方法写
NSNumber *num = [NSNumber numberWithFloat:1.0f];
②直接写
NSNumber *num = @(2);
5.iOS的三种动画
第一种:基本动画CABasicAnimation
主要属性:
fromValue:keyPath对应的初始值
toValue:keyPath对应的结束值。
CABasicAnimation常用动画的keyPath,basicAnimation的属性只能从一种值(fromValue)转为另一种值(toValue)
它的位移实际上是view.layer.position的位置变化。这里toValue指的是移动的距离而不是移动到这个点
CABasicAnimation *anima = [CABasicAnimation animation];
①位移
anima.keyPath = @"transform.translation";
anima.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
②旋转
anima.keyPath = @"transform.rotation";
anima.toValue = @(M_PI_4);
③缩放
//x、y方向同时缩放到1.5倍
anima.keyPath = @"transform.scale";
anima.toValue = @(1.5);
//x方向缩放到1.5倍
anima.keyPath = @"transform.scale.x";
anima.toValue = @(1.5);
若缩放时x、y方向的倍数不同,那么需要实例化两个animation对象,再添加到view.layer上
第二种:关键帧动画CAKeyframeAnimation
CAKeyframeAnimation可以使用NSArray保存一组动画值,比CABasicAnimation只能进行一个动画要多,它会按照元素的顺序依次执行。
主要属性:
values:用来保存动画的数组,里边的元素被称为关键帧。
paths:可以设置个CGPathRef/CGMutablePathRef,让层跟着路径走,path只对CALayer的anchorPoint和position起作用。假如设置了path,那么values将被自动忽略。
①values的动画,效果如下,就是图标抖动效果
//角度转弧度,宏定义
#define Angle2Radian(angle) ((angle)/180.0 * M_PI)
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
anima.values = @[@(Angle2Radian(-5)),@(Angle2Radian(5)),@(Angle2Radian(-5))];
②path动画,效果是view做圆形运动
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
anima.path = path.CGPath;
第三种:组动画CAAnimationGroup
CAAnimationGroup就是保存一组动画,其中的执行顺序是并行的,所有动画并行执行。这也是与CAKeyframeAnimation的区别。
主要属性:
animations : 用来保存一组动画对象的NSArray
第四种:转场动画CATransition
用来在转场时提供动画效果。
主要属性:
type:转场的动画效果
subtype:转场的动画方向
如下图的效果
点“下一张”
CATransition *anima = [CATransition animation];
anima.type = @"cube";
anima.subtype = kCATransitionFromLeft;
点“上一张”
anima.type = @"cube";
anima.subtype = kCATransitionFromRight;
layer动画结束时,若想位置不发生变化,那么需要设置两个属性
anima.removedOnCompletion = NO;
anima.fillMode = kCAFillModeForwards;
否则会返回到原位置。
核心动画(上述三个基本动画)的缺点:
做动画时,尽量使用UIView的封装动画,只有在uiview满足不了时再使用layer的动画。因为layer动画都是假象,在执行过程中,layer的position属性一直没变。在转场中常使用layer动画
//UIView的动画
[UIView animateWithDuration:0.25 animations:^{
//位移
CGRect rect;
CGPoint a = [[self.itemDesArr objectAtIndex:i] CGPointValue];
rect.size = _bottomView.frame.size;
btn.frame = rect;
btn.centerX = a.x;
btn.centerY = a.y;
//旋转
[btn.layer addAnimation:anima2 forKey:nil];
}];
6.CADisplayLink定时器一般用来UI的不停重绘,刷新频率比较高。如
-(void)testA{
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateView)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
-(void)updateView{
}
表示1秒钟执行60次updateView方法