【iOS】百叶窗动画

上周一个朋友问我会不会做百叶窗动画效果。当时一看,感觉还不会。但是想想刚好前两天做了图片的切割,百叶窗是不是就是把一个图片切割之后,再每个一起做转动的动画效果呢?经过测试,发现就是这个思路就可以做出来。下面先看效果。


代码部分就是在上一篇【iOS】Quartz 2D图片压缩和裁剪的基础上增加一些功能。所以关于图片裁剪部分的代码就不贴出来了。大家想看可以直接下载全部的工程代码。

下载请点击我。

下面就只贴百叶窗部分的代码。注释里面都有说明功能了。

//
//  BlindUnit.h
//  BYC
//
//  Copyright © 2016年 zhuming. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@protocol BlindDelegate <NSObject>

@optional
/**
 *  百叶窗动画开始实现的代理方法
 */
- (void)blindStartAnimation;
/**
 *  百叶窗动画完成后实现的代理方法
 */
- (void)blindFinishedAnimation;

@end

@interface BlindUnit : NSObject

@property (nonatomic,strong)id<BlindDelegate>delegate;

/**
 *  父视图
 */
@property (nonatomic,strong)UIView *superView;
/**
 *  百叶窗转动的动画
 */
@property (nonatomic,strong)UIImage *image;
/**
 *  水平切割的数量
 */
@property (nonatomic,assign)NSInteger separateCount;
/**
 *  切割的质量 0~1之间
 */
@property (nonatomic,assign)CGFloat cacheQuality;
/**
 *  动画得时间
 */
@property (nonatomic,assign)CFTimeInterval duration;

/**
 *  减方法 有动画完成的代理
 */
- (void)blindAnimation;

/**
 *  百叶窗
 *  无代理
 *  @param superView 父视图
 *  @param image     需要变化的图片
 *  @param x         多少个叶
 *  @param quality   切割的质量 0~1之间
 *  @param duration  动画的时间
 */
+ (void)blindAnimationInSuperView:(UIView *)superView image:(UIImage *)image separate:(NSInteger)x cacheQuality:(CGFloat)quality duration:(CFTimeInterval)duration;

@end
<pre name="code" class="objc">//
//  BlindUnit.m
//  BYC
//
//  Created by zhuming on 16/1/9.
//  Copyright © 2016年 zhuming. All rights reserved.
//

#import "BlindUnit.h"
#import "ToolUnit.h"

@interface BlindUnit ()

@property (nonatomic,assign)NSInteger startCount;
@property (nonatomic,assign)NSInteger endCount;

@end

@implementation BlindUnit

/**
 *  百叶窗动画
 */
- (void)blindAnimation{
    NSDictionary *dice = [ToolUnit separateImage:self.image separate:self.separateCount cacheQuality:self.cacheQuality];
    // 百叶窗动画
    CABasicAnimation *rotation=[CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
    rotation.duration = self.duration;
    rotation.fromValue = [NSNumber numberWithFloat:0];    // 从0°开始
    rotation.toValue = [NSNumber numberWithFloat:M_PI_2]; // 转动180°
    rotation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
    rotation.autoreverses = YES;  // 翻转后是否反向翻转
    rotation.repeatCount = 1;    // 循环次数
    rotation.delegate = self;    // 动画代理
    NSArray *keys=[dice allKeys];
    for (int count = 0; count < self.separateCount; count++)
    {
        NSString *key=[keys objectAtIndex:count];
        UIImageView *imageView=[dice objectForKey:key];
        [imageView.layer addAnimation:rotation forKey:@"rotation"];
        [self.superView addSubview:imageView];
    }
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    // 原系统代理会多次执行 执行次数就是图片分割的数量
    self.endCount ++;
    if ((self.separateCount - 1) == self.endCount) {
        //代理
        if (_delegate && [_delegate respondsToSelector:@selector(blindFinishedAnimation)]) {
            [_delegate blindFinishedAnimation];
        }
    }
}
- (void)animationDidStart:(CAAnimation *)anim{
    // 原系统代理会多次执行 执行次数就是图片分割的数量
    if (self.startCount == 0) {
        //代理
        if (_delegate && [_delegate respondsToSelector:@selector(blindStartAnimation)]) {
            [_delegate blindStartAnimation];
        }
    }
    self.startCount ++;
}

/**
 *  百叶窗
 *
 *  @param superView 父视图
 *  @param image     需要变化的图片
 *  @param x         多少个叶
 *  @param quality   切割的质量 0~1之间
 *  @param duration  动画的时间
 */
+ (void)blindAnimationInSuperView:(UIView *)superView image:(UIImage *)image separate:(NSInteger)x cacheQuality:(CGFloat)quality duration:(CFTimeInterval)duration{
    
    NSDictionary *dice = [ToolUnit separateImage:image separate:x cacheQuality:quality];
    // 百叶窗动画
    CABasicAnimation *rotation=[CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
    rotation.duration = duration;
    rotation.fromValue = [NSNumber numberWithFloat:0];    // 从0°开始
    rotation.toValue = [NSNumber numberWithFloat:M_PI_2]; // 转动180°
    rotation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
    rotation.autoreverses = NO;  // 翻转后是否反向翻转
    rotation.repeatCount = 1;    // 循环次数
    NSArray *keys=[dice allKeys];
    for (int count = 0; count < x; count++)
    {
        NSString *key=[keys objectAtIndex:count];
        UIImageView *imageView=[dice objectForKey:key];
        [imageView.layer addAnimation:rotation forKey:@"rotation"];
        [superView addSubview:imageView];
    }
}

@end


//  ViewController.m
//  BlindTest
//
//  Created by zhuming on 16/1/10.
//  Copyright (c) 2016年 zhuming. All rights reserved.
//

#import "ViewController.h"

#import "BlindUnit.h"
#import "ToolUnit.h"

@interface ViewController ()<BlindDelegate>

@property (nonatomic,strong)UIImage *image1;
@property (nonatomic,strong)UIImage *image2;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.image1 = [UIImage imageNamed:@"1"];
    self.image2 = [UIImage imageNamed:@"2"];
    self.view.backgroundColor = [UIColor orangeColor];
    [self test];
    
    [ToolUnit compressImage:self.image2 percent:0.2];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)test{
    
    //    [BlindUnit blindAnimationInSuperView:self.view image:image separate:15 cacheQuality:1 duration:3];
    
    BlindUnit *blindView = [[BlindUnit alloc] init];
    blindView.superView = self.view;
    blindView.image = self.image1;
    blindView.separateCount = 12;
    blindView.cacheQuality = 1;
    blindView.duration = 3;
    blindView.delegate = self;
    [blindView blindAnimation];
}

- (void)blindFinishedAnimation{
    NSLog(@"blindFinishedAnimation");
}
- (void)blindStartAnimation{
    NSLog(@"blindStartAnimation");
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


代码没什么好分析的了,有了思路就好做了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值