[控件] LiveChangedImageView
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的更多相关文章
- JS调用Android、Ios原生控件
在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...
- HTML5 progress和meter控件
在HTML5中,新增了progress和meter控件.progress控件为进度条控件,可表示任务的进度,如Windows系统中软件的安装.文件的复制等场景的进度.meter控件为计量条控件,表示某 ...
- 百度 flash html5自切换 多文件异步上传控件webuploader基本用法
双核浏览器下在chrome内核中使用uploadify总有302问题,也不知道如何修复,之所以喜欢360浏览器是因为帮客户控制渲染内核: 若页面需默认用极速核,增加标签:<meta name=& ...
- JS与APP原生控件交互
"热更新"."热部署"相信对于混合式开发的童鞋一定不陌生,那么APP怎么避免每次升级都要在APP应用商店发布呢?这里就用到了混合式开发的概念,对于电商网站尤其显 ...
- UWP开发必备:常用数据列表控件汇总比较
今天是想通过实例将UWP开发常用的数据列表做汇总比较,作为以后项目开发参考.UWP开发必备知识点总结请参照[UWP开发必备以及常用知识点总结]. 本次主要讨论以下控件: GridView:用于显示数据 ...
- 【踩坑速记】开源日历控件,顺便全面解析开源库打包发布到Bintray/Jcenter全过程(新),让开源更简单~
一.写在前面 自使用android studio开始,就被它独特的依赖方式:compile 'com.android.support:appcompat-v7:25.0.1'所深深吸引,自从有了它,麻 ...
- 对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传)
前言 首先声明一下,我这个是对WebUploader开源上传控件的二次封装,底层还是WebUploader实现的,只是为了更简洁的使用他而已. 下面先介绍一下WebUploader 简介: WebUp ...
- Windows API 设置窗口下控件Enable属性
参考页面: http://www.yuanjiaocheng.net/webapi/create-crud-api-1-put.html http://www.yuanjiaocheng.net/we ...
- VB.NET设置控件和窗体的显示级别
前言:在用VB.NET开发射频检测系统ADS时,当激活已存在的目标MDI子窗体时,被其他子窗体遮住了,导致目标MDI子窗体不能显示. 这个问题怎么解决呢?网上看到一篇帖子VB.NET设置控件和窗体的显 ...
随机推荐
- paxos协议更新日志
基于Paxos协议的数据同步与传统主备方式最大的区别在与Paxos只需任意超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失. Basic paxos协议更新日志 我们将数据持久 ...
- 安装Oracle需要调整的linux内核参数
在安装Oracle的时候需要调整linux的内核参数,但是各参数代表什么含义呢,下面做详细解析. Linux安装文档中给出的最小值: fs.aio-max-nr = 1048576 fs.file-m ...
- MyEclipse2014破解方法
之前一直使用的MyEclipse2014过期了,无奈之下只能在网上搜怎么破解,结果很管用,在这里记录并和大家分享 https://jingyan.baidu.com/article/fdbd42771 ...
- Node.js链式回调
由于异步的关系,代码的书写顺序可能和执行顺序并不一样,可能想先执行A再执行B,但由于异步可能B要先于A执行.例如在OC中使用AFnetworking请求数据然后刷新页面,由于网络请求是用block实现 ...
- 不停机不停服务,MYSQL可以这样修改亿级数据表结构
摘 要:本文阐述了MySQL DDL 的问题现状.pt-online-schema-change的工作原理,并实际利用pt-online-schema-change工具在线修改生产环境下1.6亿级数 ...
- visual studio 不能进入调试状态
解决Windows操作系统在处理回环地址 1. 第一种解决方案是禁用环回检查. 步骤如下 a) 依次单击“开始”和“运行”,键入 regedit,然后单击“确定” b) 在注册表编辑器中,找到并单击下 ...
- BG.Hive - part3
1. Hive数据导入 - Load Load,加载,不会进行任何数据转换和处理的操作,只会进行数据Move操作,将元数据移动到HDFS指定目录 a> hdfs dfs -put 'hdfs的h ...
- Mvc Moq HttpContext
1: public class MockMvcHttpContext 2: { 3: public Moq.Mock<System.Web.HttpContextBase> Context ...
- JavaScript 正则表达式RegExp 和字符串本身的正则表达式
JavaScript 正则表达式 正则表达式(英语:Regular Expression,在代码中常简写为regex.regexp或RE)使用单个字符串来描述.匹配一系列符合某个句法规则的字符串搜索模 ...
- ios app真正的相互!!调用
1.需求:A应用打开B.B回跳到A 2.问题: 看到网络上的文档讲的大多数都是app单向跳转的例子,而我们在跳转到第二个app的时候往往需要返回到原来的app,虽然支付宝微信等第三方等应用会有回调 ...