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. linux安装tmux

    由于tmux依赖于libevent和ncurses-devel,所以应首先有这两个库,和相关的头文件. 1.对于ncurses-devel,可用yum安装. yum install ncurses-d ...

  2. 电信固定ip宽带80与8080端口踩坑

    本文只是作为记录,避免后面遇到此类问题耗费时间. 实际情况:公司有个固定电信宽带是固定IP的,想把固定IP映射到测试环境ip,实现可以公网通过固定ip访问,内网通过局域网ip访问. 测试环境服务是占用 ...

  3. java 集合框架小结

    一:集合框架  集合框架是为表示和操作集合而规定的一种统一的标准的体系结构.  任何集合框架都包含三大块内容:对外的接口.接口的实现和对集合运算的算法.   接口:即表示集合的抽象数据类型.Colle ...

  4. spring cloud连载第三篇之Spring Cloud Netflix

    1. Service Discovery: Eureka Server(服务发现:eureka服务器) 1.1 依赖 <dependency> <groupId>org.spr ...

  5. 2013年8月12日Python的5个最有价值问题

    问:Python怎么在字典里删除值但保留相应的键 答: 假设3都在值里,而非键>>> for v in D1.values():...     if 3 in v:...       ...

  6. centos 6.5安装docker

    安装linux,需要系统内核为3.x以上,如果centos版本为7以下,先升级系统内核 1.关闭selinux setenforce 0 sed -i '/^SELINUX=/c\SELINUX=di ...

  7. Walkway.js – 创建简约的 SVG 线条动画

    Walkway.js 是一个使用线条和路径元素组成 SVG 动画图像的简单方法.只需根据提供的配置对象创建一个新的 Walkway 实例就可以了.这种效果特别适合那些崇尚简约设计风格的网页.目前, W ...

  8. Flume - 快速入门

    关于Flume,官方定义如下: Apache Flume is a distributed, reliable, and available system for efficiently collec ...

  9. [javaSE] 数组(获取最值)

    数组的常见操作(获取最值) 1.获取最值需要进行比较,每一次比较都会有一个较大的值,因为该值不确定,通过一个变量进行存储 2.让数组中的每一个元素都和这个变量中的值进行比较,如果大于了变量中的值,就用 ...

  10. eclipse启动项目报错:java.lang.ClassNotFoundException: ContextLoaderListener

    eclipse 启动项目报错:找不到 Spring 监听器类 org.springframework.web.context.ContextLoaderListener 严重: Error confi ...