设计能长按并有动画效果且能触发事件的高级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. java io流 数据流 DataInputStream、DataOutputStream、ByteArrayInputStream、ByteArrayOutputStream

    例子程序: package io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import ...

  2. redis持久化之 aof日志

    aof就是把执行的命令写到文本文件里面 aof使用过程 第一步: 修改配置文件,并启动server 第二步, 当前目录下面会生成一个 appendonly.aof文件,但是是空的 去客户端 开始操作后 ...

  3. C 扩展库 - mysql API

    MySQL API C API Data Structures MYSQL This structure represents handler for one database connection. ...

  4. C 标准库 - string.h之memmove使用

    memmove Move block of memory Copies the values of num bytes from the location pointed by source to t ...

  5. 【C#高级】泛型(一)

    泛型,.net 2.0之后出现,基本只要代码中出现 ‘<>’ 尖括号就可以确定是泛型. 在2.0之前大多是使用Object来代替,因为所有类都是Object的派生类,根据继承的原理Obje ...

  6. WPF 确认动态加载数据完成

    整个wpf程序是读取xml文件生成的,所以当数量较大而且结构复杂的时候,就会出现显示一个空白(我这里设置了背景色,所以显示黑屏,默认是空白的)的窗口,然后才显示控件. 但现在要求必须在控件显示完成后才 ...

  7. PL/SQL之游标的使用

    Oracle中的游标有两种: 显式游标 用CURSOR...IS 命令定义的游标,它可以对查询语句(SELECT)返回的多条记录进行处理. 隐式游标 是在执行插入(INSERT).删除(DELETE) ...

  8. C#制作手机网站

    <meta name="viewport" content="width=device-width, initial-scale=1.0"> //在 ...

  9. hdu 4193 Non-negative Partial Sums 单调队列。

    Non-negative Partial Sums Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  10. Java数据库操作(JDBC)

    JDBC Java数据库连接(Java DataBase Connectivity,JDBC)用于在Java程序中实现数据库操作功能,它提供了执行SQL语句.访问各种数据库的方法,并为各种不同的数据库 ...