设计能长按并有动画效果且能触发事件的高级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. hibernate关联关系的crud2

    hibernate关联关系的CRUD操作,解释都在注释里了,讲了fetchType.cascade. User类: package com.oracle.hibernate; import javax ...

  2. IPC之AIDL&binder关系

    binder是一个远程对象的基础类,核心部分是远程调用机制,这部分是由IBinder定义的.它是对IBinder类的实现,其中IBinder类提供这样一个类的标准的本地化实现方式. 大多数开发者不会去 ...

  3. Microsoft Power BI Desktop概念学习系列之Microsoft Power BI Desktop的下载和安装(图文详解)

    不多说,直接上干货! 官网 https://powerbi.microsoft.com/zh-cn/downloads/ 这里,一般用126邮箱. 因为对于163这样的邮箱是不行. 欢迎大家,加入我的 ...

  4. python 四种单例模式

    1 使用__new__方法 Python class Singleton(object): def __new__(cls, *args, **kw): if not hasattr(cls, '_i ...

  5. xcode发布ipa

    --------Xcode------- product 产品 archive 存档 (等) distribute app 分发app development 开发者 next next (等 比较漫 ...

  6. 我爱Markdown (2)

    Markdown的语法很简单,所以很容易上手.下面介绍一下常用的Markdown的语法, 本文将介绍: 01 - Back-ticks 反尖号 02 - Headers 标题 03 - Emphasi ...

  7. hadoop nameNode 无法启动

    /************************************************************STARTUP_MSG: Starting NameNodeSTARTUP_M ...

  8. 发布 .Net Core WebAPI 应用程序到 Docker

    目录 1. 创建 .net core webapi 项目 2. 编译应用 3. 创建 Dockerfile 文件 4. 上传文件到服务器 5. 生成Docker Image 6. 在Docker Co ...

  9. android的计算器

    今天我闲着无聊,便想仿照Iphone的计算器自己写一个出来玩玩,于是就开动脑经,来场头脑风暴了!我拿什么了写呢?wp?这是个不错的选择,但是我最近在研究安卓的开发(求各位MSP不要烧我,我买不起MAC ...

  10. eclipse下JAVA的搭建

    练手JAVA用eclipse比android studio快很多,android studio啥都好,就是太慢 参考资料:http://blog.csdn.net/21aspnet/article/d ...