设计能长按并有动画效果且能触发事件的高级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的更多相关文章

  1. Android 动画效果 及 自定义动画

    1. View动画-透明动画效果2. View动画-旋转动画效果3. View动画-移动动画效果4. View动画-缩放动画效果5. View动画-动画效果混合6. View动画-动画效果侦听7. 自 ...

  2. Flex 动画效果

    1.使用自带效果 在Flex里面不像在Flash里面随意制作动画了,Flex更趋向于应用程序,而不是动画制作了,所以没有了时间轴的概念.在Flex中使用动画效果,可以用Flex自带的Effect,或者 ...

  3. UI设计篇·入门篇·简单动画的实现,透明动画/旋转动画/移动动画/缩放动画,混合动画效果的实现,为动画设置监听事件,自定义动画的方法

    基本的动画构成共有四种:透明动画/旋转动画/移动动画/缩放动画. 配置动画的方式有两种,一种是直接使用代码来配置动画效果,另一种是使用xml文档配置动画效果 相比而言,用xml文档写出来的动画效果,写 ...

  4. 使用Canvas实现动画效果 | DKlogs -- 设计 | 生活

    使用Canvas实现动画效果 | DKlogs -- 设计 | 生活 使用Canvas实现动画效果

  5. 【Android UI设计与开发】10:滑动菜单栏(二)SlidingMenu 动画效果的实现

    其实就是在显示菜单栏时,有个动画的效果.代码比较简单,下面进行说明. 1.效果图如下,手机上查看效果更佳 2.代码实现,这里只讲解动画效果的实现,具体代码可在源代码中查看 <1> 先定义一 ...

  6. 【Android UI设计与开发】第03期:引导界面(三)仿微信引导界面以及动画效果

    基于前两篇比较简单的实例做铺垫之后,这一篇我们来实现一个稍微复杂一点的引导界面的效果,当然也只是稍微复杂了一点,对于会的人来说当然还是so easy!正所谓会者不难,难者不会,大概说的就是这个意思了吧 ...

  7. 运动曲线提升CSS动画效果

    原文链接 译文\译者鞠大宝 先有UI动画,然后才会有好的UI动画.好的动画会让人惊叹“哇哦!”——因为页面看上去很流畅.很漂亮,最重要的是,自然,一点都不会让人觉得不和谐或者僵硬死板.如果你经常逛Dr ...

  8. 纯CSS3画出小黄人并实现动画效果

    前言 前两天我刚发布了一篇CSS3实现小黄人动画的博客,但是实现的CSS3动画是基于我在站酷网找到的一张小黄人的jpg格式图片,并自己用PS抠出需要实现动画的部分,最后才完成的动画效果.但是,其实我的 ...

  9. 更新——Canvas画布动画效果之实现倒计时

    Hello,大家好! 小W复活啦!继续欢乐的给大家更博,输送新知识~~ 不开玩笑啦!秒进正题~~~ 上次更博,小W给大家介绍了Canvas画布的基础部分,以及实现了一个由7*10点阵图显示的倒计时的基 ...

随机推荐

  1. 【ZooKeeper】单机伪集群搭建(适用于mac)

    1.配置 .zookeeper下载地址:http://apache.mirrors.lucidnetworks.net/zookeeper/ 可以选择需要的版本,我下载的是zookeeper-3.4. ...

  2. 利用IDEA创建Web Service服务端和客户端的详细过程

    创建服务端 一.file–>new–>project 二.点击next后输入服务端名,点击finish,生成目录如下 三.在 HelloWorld.Java 文件中右击,选 WebServ ...

  3. redis 远程 访问 安全配置

    朋友总结很好,就转载了-> 站长博客 假设两台redis服务器,ip分别为:192.168.1.101和192.168.1.103,如果在101上通过redis-cli访问103上的redis呢 ...

  4. OAuth机制原理(开放授权机制)

    1.简述 OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是安全的. 国 ...

  5. Java 实现两个整数变量的交换

    class OperatorTest { public static void main(String[] args) { int a = 10; int b = 20; System.out.pri ...

  6. Java reflect 反射 0 java对象的三个阶段

  7. iOS 性能优化套路

    ***  一级套路 ***  使用ARC管理内存- 防止内存泄露- 保证释放掉不再需要的内存,提高性能 在正确的地方使用 reuseIdentifier平时接触的需要考虑重用的视图有UICollect ...

  8. 第一章:初识PHP

    Web程序工作原理介绍? 工作方式? 浏览器首先向Web服务器发出请求,Web服务器对请求做出响应,将响应数据发送给客户端浏览器,通常是一个HTML文件,然后通过浏览器把HTML文件信息显示在屏幕上. ...

  9. JavaScript对象——原型与原型链

    原型与原型链 一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object .Function 是 JS 自带的函数对象.下面举例说明 va ...

  10. XmlSerializer序列化

    XmlSerializer在命名空间using System.Xml.Serialization下. 序列化和反序列化的代码: using System.IO; using System.Xml; u ...