美文网首页
3.视图动画

3.视图动画

作者: LucXion | 来源:发表于2021-09-26 11:11 被阅读0次
  • UIView提供的动画功能 +animationWithDuration:Animations:

,可以为frame、bounds、center、transform、alpha、backgroundColor、contentStretch添加动画效果。

  • 视图动画中默认停止响应用户交互
  • UIView是一个相当重量级的对象,管理绘制与时间处理,CALayer完全关乎绘制。
    • 图层会在它的contents属性中绘制任意东西,可以通过设置CGImage来直接分配,否则会走如下代理。
    • [CALayer setNeedsDisplay],需要代码调用,将图层标记为需要重绘。
    • [CALayer displayIfNeeded],绘图系统会在需要时自动调用它
    • [CALayer display],displayIfNeed会在合适的时候调用它,开发者不应该直接调用。
    • 如果有实现委托方法 displayLayer: 系统会调用,否则display会调用drawInContext:,可以在子类中覆盖display方法设置contents属性。

隐式动画

Core Animation 把属性的更改绑定到了原子事务CATransAction,当你首次在一个包含运行循环的线程上修改一个图层时,系统会为你创建一个隐式的 CATransAction,在运行循环中,所有的图层修改都被收集起来,当运行循环结束时,所有的修改都提交给图层树。

opacitybackgroundColor

显示动画

CAAnimation

动画闪回问题

CAAnimation 创建副本作为视图的表示层,但真实的模型层没有发生改变,绘制完成后,所有的表示层都会被丢弃并由模型层决定新形态。

避免显示动画、隐式动画冲突:

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    // 执行相关代码
    [CATransaction commit];

使用removeOnCompletion为NO,或者fillModekCAFillModeBoth并不是好的办法,这意味着动画会一直执行,且模型层不会更新。会造成给属性再次添加隐式动画可能不能正常工作,调用removeAnimation会获取旧值。这么设置也会浪费内存。

可转动的六边形代码示例 1

@interface ViewController ()

@property (nonatomic,strong) CALayer *top;
@property (nonatomic,strong) CALayer *bottom;
@property (nonatomic,strong) CALayer *left;
@property (nonatomic,strong) CALayer *right;
@property (nonatomic,strong) CALayer *front;
@property (nonatomic,strong) CALayer *back;

@end

const CGFloat kSize = 100.;
const CGFloat kPanScale = 1/100.;

@implementation ViewController
  
- (void)viewDidLoad {
    [super viewDidLoad];
   
    CATransform3D transform;
    
    transform = CATransform3DMakeTranslation(0, -kSize/2, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 1.0, 0, 0);
    self.top = [self layerWithColor:[UIColor redColor] andTransfrom:transform];
    
    transform = CATransform3DMakeTranslation(0, kSize/2, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 1.0, 0, 0);
    self.bottom = [self layerWithColor:[UIColor greenColor] andTransfrom:transform];
    
    transform = CATransform3DMakeTranslation(kSize/2, 0, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 1.0, 0);
    self.right = [self layerWithColor:[UIColor blueColor] andTransfrom:transform];
    
    transform = CATransform3DMakeTranslation(-kSize/2, 0, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 1.0, 0);
    self.right = [self layerWithColor:[UIColor grayColor] andTransfrom:transform];
    
    transform = CATransform3DMakeTranslation(0, 0, -kSize/2);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 0, 0);
    self.back = [self layerWithColor:[UIColor yellowColor] andTransfrom:transform];
    
    transform = CATransform3DMakeTranslation(0, 0, kSize/2);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 0, 0);
    self.front = [self layerWithColor:[UIColor purpleColor] andTransfrom:transform];
    
    self.view.layer.sublayerTransform = MakePerspectiveTransform();
    
    UIGestureRecognizer *g = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];
    [self.view addGestureRecognizer:g];
}

- (void)pan:(UIPanGestureRecognizer*)recognizer {
    CGPoint translation = [recognizer translationInView:self.view];
    CATransform3D transform = MakePerspectiveTransform();
    transform = CATransform3DRotate(transform, kPanScale * translation.x, 0, 1, 0);
    transform = CATransform3DRotate(transform, -kPanScale * translation.y, 1, 0, 0);
    
    self.view.layer.sublayerTransform = transform;
}

- (CALayer*)layerWithColor:(UIColor*)color andTransfrom:(CATransform3D)transform {
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = color.CGColor;
    layer.transform = transform;
    layer.position = self.view.center;
    layer.bounds = CGRectMake(0, 0, kSize, kSize);
    
    [self.view.layer addSublayer:layer];
    
    return layer;
}

static CATransform3D MakePerspectiveTransform (){
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1./2000.;
    return perspective;
}
@end

可转动的六边形代码示例 2

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic,strong) CALayer *top;
@property (nonatomic,strong) CALayer *bottom;
@property (nonatomic,strong) CALayer *left;
@property (nonatomic,strong) CALayer *right;
@property (nonatomic,strong) CALayer *front;
@property (nonatomic,strong) CALayer *back;

@property (nonatomic,strong) CATransformLayer *contentLayer;

@end

const CGFloat kSize = 100.;
const CGFloat kPanScale = 1/100.;

@implementation ViewController
  
- (void)viewDidLoad {
    [super viewDidLoad];
   
    CATransformLayer *layer = [CATransformLayer layer];
    layer.frame = self.view.layer.bounds;
    
    CGSize size = layer.bounds.size;
    layer.transform = CATransform3DMakeTranslation(size.width/2, size.height/2, 0);
    
    [self.view.layer addSublayer:layer];
    self.contentLayer = layer;
    
    CATransform3D transform;
        transform = CATransform3DMakeTranslation(0, -kSize/2, 0);
        transform = CATransform3DRotate(transform, M_PI_2, 1.0, 0, 0);
    self.top = [self layerWithX:0 Y:-kSize/2 Z:0 Color:[UIColor redColor] andTransfrom:transform];
    
    transform = CATransform3DMakeTranslation(0, kSize/2, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 1.0, 0, 0);
    self.bottom = [self layerWithX:0 Y:kSize/2 Z:0 Color:[UIColor orangeColor] andTransfrom:transform];

    transform = CATransform3DMakeTranslation(kSize/2, 0, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 1.0, 0);
    self.right = [self layerWithX:kSize/2 Y:0 Z:0 Color:[UIColor blueColor] andTransfrom:transform];
    
    transform = CATransform3DMakeTranslation(-kSize/2, 0, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 1.0, 0);
    self.left = [self layerWithX:-kSize/2 Y:0 Z:0 Color:[UIColor greenColor] andTransfrom:transform];

    transform = CATransform3DMakeTranslation(0, 0, -kSize/2);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 0, 0);
    self.back = [self layerWithX:0 Y:0 Z:-kSize/2 Color:[UIColor yellowColor] andTransfrom:transform];

    transform = CATransform3DMakeTranslation(0, 0, kSize/2);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 0, 0);
    self.back = [self layerWithX:0 Y:0 Z:kSize/2 Color:[UIColor purpleColor] andTransfrom:transform];
    
    UIGestureRecognizer *g = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];
    [self.view addGestureRecognizer:g];
}

- (void)pan:(UIPanGestureRecognizer*)recognizer {
    CGPoint translation = [recognizer translationInView:self.view];
    CATransform3D transform = CATransform3DIdentity;
    transform = CATransform3DRotate(transform, kPanScale * translation.x, 0, 1, 0);
    transform = CATransform3DRotate(transform, -kPanScale * translation.y, 1, 0, 0);
    
    self.view.layer.sublayerTransform = transform;
}

- (CALayer*)layerWithX:(CGFloat)x Y:(CGFloat)y Z:(CGFloat)z Color:(UIColor*)color andTransfrom:(CATransform3D)transform{
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = color.CGColor;
    layer.transform = transform;
    layer.bounds = CGRectMake(0, 0, kSize, kSize);
    
    layer.position = CGPointMake(x, y);
    layer.zPosition = z;
    
    [self.contentLayer addSublayer:layer];
    
    return layer;
}
@end

相关文章

网友评论

      本文标题:3.视图动画

      本文链接:https://www.haomeiwen.com/subject/eyrqnltx.html