LiveChangedImageView

效果

说明

切换图片的时候自动根据图片的尺寸进行渐变式切换,效果很不错,使用非常容易。

源码

https://github.com/YouXianMing/UI-Component-Collection

//
// LiveChangedImageView.h
// LiveImageView
//
// Created by YouXianMing on 15/5/1.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import <UIKit/UIKit.h> @interface LiveChangedImageView : UIView /**
* 动画持续时间(默认值为0.3s)
*/
@property (nonatomic) NSTimeInterval duration; /**
* 原始的图片(只需要赋值一次,重写了setter方法,要注意)
*/
@property (nonatomic, strong) UIImage *image; /**
* 变化到的图片
*/
@property (nonatomic, strong) UIImage *changeToImage; /**
* 边框大小
*/
@property (nonatomic) CGFloat borderWidth; /**
* 边框颜色
*/
@property (nonatomic, strong) UIColor *borderColor; /**
* 变化时候的动画
*
* @param animated 是否执行动画
*/
- (void)changedAnimation:(BOOL)animated; /* ==========================
----- 简化操作的方法 -----
========================== */ /**
* 便利构造器
*
* @param frame frame值
* @param duration 动画持续时间
* @param image 原始的图片
*
* @return 实例对象
*/
+ (instancetype)liveChangedImageViewWithFrame:(CGRect)frame
duration:(NSTimeInterval)duration
startImage:(UIImage *)image; /**
* 切换到其他图片
*
* @param image 被切换的图片
* @param animated 是否执行动画
*/
- (void)changeToImage:(UIImage *)image animated:(BOOL)animated; @end
//
// LiveChangedImageView.m
// LiveImageView
//
// Created by YouXianMing on 15/5/1.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import "LiveChangedImageView.h" @interface LiveChangedImageView () @property (nonatomic, strong) UIImageView *imageView; @end @implementation LiveChangedImageView /**
* 创建出imageView
*
* @param frame imageView的frame值
*/
- (void)createImageView:(CGRect)frame { self.imageView = [[UIImageView alloc] initWithFrame:frame];
[self addSubview:self.imageView]; } - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) { [self createImageView:self.bounds]; self.duration = 0.3f; }
return self;
} - (void)changedAnimation:(BOOL)animated { if (_changeToImage == nil) {
return;
} // 如果设定了动画
if (animated) { // 设定切换动画
CABasicAnimation *contentsAnimation = [CABasicAnimation animationWithKeyPath:@"contents"];
contentsAnimation.duration = _duration;
contentsAnimation.fromValue = (__bridge id)(_imageView.image.CGImage);
contentsAnimation.toValue = (__bridge id)(_changeToImage.CGImage);
_imageView.layer.contents = (__bridge id)(_changeToImage.CGImage); // 设定尺寸动画
CGRect startRect = CGRectMake(, , _imageView.image.size.width, _imageView.image.size.height);
CGRect endRect = CGRectMake(, , _changeToImage.size.width, _changeToImage.size.height); CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];
boundsAnimation.duration = _duration;
boundsAnimation.fromValue = [NSValue valueWithCGRect:startRect];
boundsAnimation.toValue = [NSValue valueWithCGRect:endRect];
_imageView.layer.bounds = endRect; // 动画组
CAAnimationGroup *group = [CAAnimationGroup animation];
group.duration = _duration;
group.animations = @[contentsAnimation, boundsAnimation];
group.delegate = self; // 加载动画
[_imageView.layer addAnimation:group forKey:nil]; } else { _imageView.image = _changeToImage;
_imageView.bounds = CGRectMake(, , _changeToImage.size.width, _changeToImage.size.height); }
} #pragma mark - 动画代理
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
_imageView.image = _changeToImage;
} + (instancetype)liveChangedImageViewWithFrame:(CGRect)frame
duration:(NSTimeInterval)duration
startImage:(UIImage *)image {
LiveChangedImageView *changedView = [[LiveChangedImageView alloc] initWithFrame:frame];
changedView.image = image;
changedView.duration = duration; return changedView;
} - (void)changeToImage:(UIImage *)image animated:(BOOL)animated {
self.changeToImage = image;
[self changedAnimation:animated];
} #pragma mark - 重写setter,getter方法
@synthesize image = _image;
- (void)setImage:(UIImage *)image {
_image = image;
_imageView.image = image;
_imageView.bounds = CGRectMake(, , image.size.width, image.size.height);
} - (UIImage *)image {
return _imageView.image;
} @synthesize borderColor = _borderColor;
- (void)setBorderColor:(UIColor *)borderColor {
_imageView.layer.borderColor = borderColor.CGColor;
_borderColor = borderColor;
} - (UIColor *)borderColor {
return _borderColor;
} @synthesize borderWidth = _borderWidth;
- (void)setBorderWidth:(CGFloat)borderWidth {
_imageView.layer.borderWidth = borderWidth;
_borderWidth = borderWidth;
} - (CGFloat)borderWidth {
return _borderWidth;
} @end

设计细节

[控件] LiveChangedImageView的更多相关文章

  1. JS调用Android、Ios原生控件

    在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...

  2. HTML5 progress和meter控件

    在HTML5中,新增了progress和meter控件.progress控件为进度条控件,可表示任务的进度,如Windows系统中软件的安装.文件的复制等场景的进度.meter控件为计量条控件,表示某 ...

  3. 百度 flash html5自切换 多文件异步上传控件webuploader基本用法

    双核浏览器下在chrome内核中使用uploadify总有302问题,也不知道如何修复,之所以喜欢360浏览器是因为帮客户控制渲染内核: 若页面需默认用极速核,增加标签:<meta name=& ...

  4. JS与APP原生控件交互

    "热更新"."热部署"相信对于混合式开发的童鞋一定不陌生,那么APP怎么避免每次升级都要在APP应用商店发布呢?这里就用到了混合式开发的概念,对于电商网站尤其显 ...

  5. UWP开发必备:常用数据列表控件汇总比较

    今天是想通过实例将UWP开发常用的数据列表做汇总比较,作为以后项目开发参考.UWP开发必备知识点总结请参照[UWP开发必备以及常用知识点总结]. 本次主要讨论以下控件: GridView:用于显示数据 ...

  6. 【踩坑速记】开源日历控件,顺便全面解析开源库打包发布到Bintray/Jcenter全过程(新),让开源更简单~

    一.写在前面 自使用android studio开始,就被它独特的依赖方式:compile 'com.android.support:appcompat-v7:25.0.1'所深深吸引,自从有了它,麻 ...

  7. 对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传)

    前言 首先声明一下,我这个是对WebUploader开源上传控件的二次封装,底层还是WebUploader实现的,只是为了更简洁的使用他而已. 下面先介绍一下WebUploader 简介: WebUp ...

  8. Windows API 设置窗口下控件Enable属性

    参考页面: http://www.yuanjiaocheng.net/webapi/create-crud-api-1-put.html http://www.yuanjiaocheng.net/we ...

  9. VB.NET设置控件和窗体的显示级别

    前言:在用VB.NET开发射频检测系统ADS时,当激活已存在的目标MDI子窗体时,被其他子窗体遮住了,导致目标MDI子窗体不能显示. 这个问题怎么解决呢?网上看到一篇帖子VB.NET设置控件和窗体的显 ...

随机推荐

  1. SpringMVC和dubbo简单的整合(附Demo)

    顺便记录下apache产品提供下载的网址:http://mirrors.shuosc.org/apache/ 第一步: 下载zookeeper,网址:http://mirrors.shuosc.org ...

  2. redis-redisTemplate模糊匹配删除

    前几天需要一个模糊删除redis中key的功能, 没有多想,  直接 String key = "noteUserListenedPoi:*"; redisTemplate.del ...

  3. Node.js最新Web技术栈(2016年4月)

    Node.js是比较简单的,只有你有前端js基础,那就按照我的办法来吧!一周足矣,虽然这版上了es语法,但依然是可以简单写,也可以难写,参见<全栈工程师之路-Node.js>,里面讲了No ...

  4. 【LeetCode题解】136_只出现一次的数字

    目录 [LeetCode题解]136_只出现一次的数字 描述 方法一:列表操作 思路 Java 实现 Python 实现 方法二:哈希表 思路 Java 实现 Python 实现 方法三:数学运算 思 ...

  5. Behave step matcher

    behave 提供3中step匹配模式 'parse' 'cfparse' 基于parse的扩展,  支持cardinality field syntax? 're' 支持在step中定义正则表达式 ...

  6. Node.js中Process.nextTick()和setImmediate()的区别

    一.Webstrom使用node.js IDE的问题 在区别这两个函数之前来说一下Webstrom使用node.js IDE的问题,在配置Node.js的IDE了,但setImmediate().re ...

  7. 撩课-Web大前端每天5道面试题-Day23

    1.为什么用Nodejs,它有哪些优缺点? 优点: 事件驱动,通过闭包很容易实现客户端的生命活期. 不用担心多线程,锁,并行计算的问题 V8引擎速度非常快 对于游戏来说,写一遍游戏逻辑代码,前端后端通 ...

  8. Redis到底是多线程还是单线程?线程安全吗

    redis是单线程,线程安全 redis可以能够快速执行的原因: (1) 绝大部分请求是纯粹的内存操作(非常快速)(2) 采用单线程,避免了不必要的上下文切换和竞争条件(3) 非阻塞IO - IO多路 ...

  9. 关于DNS缓存

  10. 关于Dubbo异常之Data length too large

    最近几日发现生产环境项目打出的日志,每天都在30~50G以上,寻找多次发现问题: 首先查看日志只看到大批量的json数据输出,这是方法查询后的返回值输出,期初以为是自己打了logger,结果寻找多次, ...