设计能长按并有动画效果且能触发事件的高级view
设计能长按并有动画效果且能触发事件的高级view

效果图:

源码:
LongTapAnimationView.h 与 LongTapAnimationView.m
//
// LongTapAnimationView.h
// YouXianMingClock
//
// Created by YouXianMing on 14-10-13.
// Copyright (c) 2014年 YouXianMing. All rights reserved.
// #import <UIKit/UIKit.h>
@class LongTapAnimationView; @protocol LongTapAnimationViewDelegate <NSObject>
/**
* 长按百分比
*
* @param percent 百分比
* @param view 自身
*/
- (void)longPressPercentage:(CGFloat)percent view:(LongTapAnimationView *)view;
- (void)longPressCompleteWithView:(LongTapAnimationView *)view;
@end @interface LongTapAnimationView : UIView /**
* 代理
*/
@property (nonatomic, assign) id<LongTapAnimationViewDelegate> delegate; /**
* 百分比
*/
@property (nonatomic, assign, readonly) CGFloat percent; /**
* 缩放比例
*/
@property (nonatomic, assign) CGFloat scaleValue; /**
* 时候允许按下(默认为YES)
*/
@property (nonatomic, assign) BOOL canTouch; /**
* 长按时间多长时间才能表示已经按下按钮激活事件
*/
@property (nonatomic, assign) NSTimeInterval completeDurationAfterLongPress; /**
* 激活按钮事件
*/
- (void)activateButtonEffect; @end
//
// LongTapAnimationView.m
// YouXianMingClock
//
// Created by YouXianMing on 14-10-13.
// Copyright (c) 2014年 YouXianMing. All rights reserved.
// #import "LongTapAnimationView.h"
#import "POP.h" @interface LongTapAnimationView ()<POPAnimationDelegate> @property (nonatomic, strong) UIButton *button; @end @implementation LongTapAnimationView - (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) { // 完整显示按住按钮后的动画效果
_button = [[UIButton alloc] initWithFrame:self.bounds];
[self addSubview:_button]; // 按住按钮后没有松手的动画
[_button addTarget:self
action:@selector(scaleToSmall)
forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter]; // 按住按钮松手后的动画
[_button addTarget:self
action:@selector(scaleAnimations)
forControlEvents:UIControlEventTouchUpInside]; // 按住按钮后拖拽出去的动画
[_button addTarget:self
action:@selector(scaleToDefault)
forControlEvents:UIControlEventTouchDragExit]; _button.userInteractionEnabled = NO;
}
return self;
} /**
* 在设定frame值的时候也设置button的frame值
*
* @param frame 当前view的frame值
*/
- (void)setFrame:(CGRect)frame {
[super setFrame:frame];
_button.bounds = frame;
} - (void)scaleToSmall
{
CGFloat tmpScale = (_scaleValue > )? _scaleValue : 0.7f; // 变小尺寸
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(tmpScale, tmpScale)];
scaleAnimation.delegate = self; // 核心
[self.layer pop_addAnimation:scaleAnimation forKey:nil];
[self performSelector:@selector(performSelectorEvent)
withObject:nil
afterDelay:(_completeDurationAfterLongPress > 1.5 ? _completeDurationAfterLongPress : 1.5)];
} - (void)scaleToDefault
{
// 恢复尺寸
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(.f, .f)];
scaleAnimation.delegate = self; // 核心
[self.layer pop_addAnimation:scaleAnimation forKey:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
} - (void)scaleAnimations
{
// 恢复尺寸
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(.f, .f)];
scaleAnimation.delegate = self; // 核心
[self.layer pop_addAnimation:scaleAnimation forKey:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
} - (void)performSelectorEvent
{
if (_delegate) {
[_delegate longPressCompleteWithView:self];
}
} /**
* POP动画代理
*
* @param anim 执行动画的那个对象
*/
- (void)pop_animationDidApply:(POPAnimation *)anim
{
NSValue *toValue = (NSValue *)[anim valueForKeyPath:@"currentValue"];
CGSize size = [toValue CGSizeValue];
CGFloat tmpScale = (_scaleValue > )? _scaleValue : 0.7f;
_percent = (size.height - calculateConstant(, , , tmpScale))/calculateSlope(, , , tmpScale);
if (_delegate) {
[_delegate longPressPercentage:_percent view:self];
}
} CGFloat calculateSlope(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2)
{
return (y2 - y1) / (x2 - x1);
} CGFloat calculateConstant(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2)
{
return (y1*(x2 - x1) - x1*(y2 - y1)) / (x2 - x1);
} - (void)addSubview:(UIView *)view
{
[super addSubview:view]; /**
* 如果继承了这个类,则子类不会执行以下方法
*/
if ([self class] == [LongTapAnimationView class]) {
[self bringSubviewToFront:_button];
}
} - (void)activateButtonEffect
{
[self bringSubviewToFront:_button];
} #pragma mark - 重写setter,getter方法
@synthesize canTouch = _canTouch;
- (void)setCanTouch:(BOOL)canTouch {
_canTouch = canTouch;
_button.userInteractionEnabled = canTouch;
}
- (BOOL)canTouch {
return _canTouch;
} @end
笔者设计这个类可谓用心良苦,Facebook是业界良心啊!以下是使用细节:


设计能长按并有动画效果且能触发事件的高级view的更多相关文章
- Android 动画效果 及 自定义动画
1. View动画-透明动画效果2. View动画-旋转动画效果3. View动画-移动动画效果4. View动画-缩放动画效果5. View动画-动画效果混合6. View动画-动画效果侦听7. 自 ...
- Flex 动画效果
1.使用自带效果 在Flex里面不像在Flash里面随意制作动画了,Flex更趋向于应用程序,而不是动画制作了,所以没有了时间轴的概念.在Flex中使用动画效果,可以用Flex自带的Effect,或者 ...
- UI设计篇·入门篇·简单动画的实现,透明动画/旋转动画/移动动画/缩放动画,混合动画效果的实现,为动画设置监听事件,自定义动画的方法
基本的动画构成共有四种:透明动画/旋转动画/移动动画/缩放动画. 配置动画的方式有两种,一种是直接使用代码来配置动画效果,另一种是使用xml文档配置动画效果 相比而言,用xml文档写出来的动画效果,写 ...
- 使用Canvas实现动画效果 | DKlogs -- 设计 | 生活
使用Canvas实现动画效果 | DKlogs -- 设计 | 生活 使用Canvas实现动画效果
- 【Android UI设计与开发】10:滑动菜单栏(二)SlidingMenu 动画效果的实现
其实就是在显示菜单栏时,有个动画的效果.代码比较简单,下面进行说明. 1.效果图如下,手机上查看效果更佳 2.代码实现,这里只讲解动画效果的实现,具体代码可在源代码中查看 <1> 先定义一 ...
- 【Android UI设计与开发】第03期:引导界面(三)仿微信引导界面以及动画效果
基于前两篇比较简单的实例做铺垫之后,这一篇我们来实现一个稍微复杂一点的引导界面的效果,当然也只是稍微复杂了一点,对于会的人来说当然还是so easy!正所谓会者不难,难者不会,大概说的就是这个意思了吧 ...
- 运动曲线提升CSS动画效果
原文链接 译文\译者鞠大宝 先有UI动画,然后才会有好的UI动画.好的动画会让人惊叹“哇哦!”——因为页面看上去很流畅.很漂亮,最重要的是,自然,一点都不会让人觉得不和谐或者僵硬死板.如果你经常逛Dr ...
- 纯CSS3画出小黄人并实现动画效果
前言 前两天我刚发布了一篇CSS3实现小黄人动画的博客,但是实现的CSS3动画是基于我在站酷网找到的一张小黄人的jpg格式图片,并自己用PS抠出需要实现动画的部分,最后才完成的动画效果.但是,其实我的 ...
- 更新——Canvas画布动画效果之实现倒计时
Hello,大家好! 小W复活啦!继续欢乐的给大家更博,输送新知识~~ 不开玩笑啦!秒进正题~~~ 上次更博,小W给大家介绍了Canvas画布的基础部分,以及实现了一个由7*10点阵图显示的倒计时的基 ...
随机推荐
- Tomcat *的安装和运行(绿色版和安装版都适用)
不多说,直接上干货! 前提, Tomcat *的下载(绿色版和安装版都适用) 一.Tomcat的安装版 1.新建安装目录 2.放置安装版的tomcat 3.双击 4.点击 I agree 5.选择“F ...
- 全网最详细的Git学习系列之安装各个Git图形客户端(Windows、Linux、Mac系统皆适用ing)(图文详解)
不多说,直接上干货! 目前Git图形客户端 TortoiseGit .SourceTree .GitUp .SmartGit .QGit .GitX .Gitnub.Tower .Git-cola . ...
- 定时删除elasticsearch索引
从去年搭建了日志系统后,就没有去管它了,最近发现大半年各种日志的index也蛮多的,就想着写个脚本定时清理一下,把一些太久的日志清理掉. 脚本思路:通过获取index的尾部时间与我们设定的过期时间进行 ...
- JVM的类加载时机
类加载过程中每个步骤的顺序 我们已经知道,类加载的过程包括:加载.连接.初始化,连接又分为:验证.准备.解析,所以说类加载一共分为5步:加载.验证.准备.解析.初始化. 其中加载.验证.准备.初始化的 ...
- 利用css实现搜索过滤
无意中找到一种利用css就可实现的搜索过滤的方法,不得不说看了代码之后确实被惊艳到了,亏我之前面试还因为做这个功能做太慢而拖了后腿.在此记录下代码: <!DOCTYPE html> < ...
- [shell进阶]——shell多线程
关于shell的多线程 1. 多线程并发执行任务,而不用一台台的串行执行,能更快更高效 2. Shell并没有多线程的概念,所以: * 一般使用wait.read等命令技巧性地模拟多线程实 * 使用命 ...
- 去除tableView表头悬浮
UITableView设置为UITableViewStyleGrouped样式会出现多余间距,以前遇到过这样的问题,自己以为不难,只是一个知识点,也没太在意 ,今天又碰到了,发现自己把它给忘了,所以还 ...
- Unity 动态加载资源的方式。
方式 特点 用法 Resource.load 安装包会比较大 在Asset文件夹下建一个Resources命名的文件夹,在打包安装包时会把 Resources文件夹下的所有文件都打包进去,不管 ...
- RabbitMQ---4、消息确认Ack
一:消费者确认 消费者确认或者说消费者应答指的是RabbitMQ需要确认消息到底有没有被收到 - 自动应答 boolean autoAck = true; channel.basicConsume(Q ...
- SSM框架文件远程服务器下载
1.首先你必须要建立连接 获取URL的输入流 2.之后就是文件读取和写入了 3.还有就是设置响应头,响应码等 代码 @RequestMapping("/fileDownLoad") ...