设计能长按并有动画效果且能触发事件的高级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 > 0)? _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(1.f, 1.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(1.f, 1.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 > 0)? _scaleValue : 0.7f;
    _percent         = (size.height - calculateConstant(0, 1, 1, tmpScale))/calculateSlope(0, 1, 1, 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是业界良心啊!以下是使用细节:

时间: 2024-10-15 05:53:22

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

页面跳转的时候有动画效果

原来在跳转到另外一个页面的时候,是可以有动画效果的.上代码. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { /* 1,不使用动画 UIViewAnimationTransitionNone 2,从左向右旋转翻页 UIViewAnimationTransitionFlipFromLeft 3,从右向左旋转翻页,与UIViewAnimationTransitionFlipFromLeft相反 UIViewAnima

Android实现GridView的item长按拖动删除实现(带动画效果)

领导这几天让做一个项目,就是可以实现像支付宝首页一样的可以长按拖动,删除的界面,以前没做过,领导让我做的时候觉得简直是老虎吃天,无从下手啊,可是领导的任务还是要实现的,没办法,就自己网上找咯,但是网上的demo五花八门无法满足我的需求,而且bug还很多,所以最后就自己实现了,说实话,这个效果困扰了我好几个星期,因为其中牵扯的知识点太多了,什么事件分发机制,动画效果,互换位置的算法,还有拖动,这些我都没有接触过,所以只有一点一点来做咯,如果大家还没有了解过这些知识点,我建议搭建先去了解一下,毕竟这

使用maskView设计动画效果

在 极客学院 简单学习了一下 如何使用maskView设计动画效果 主要是通过CAGradientLayer 或者 带有alpha的图片来操作 //MARK:1. maskView(maskLayer)基本原理 CGFloat width = 120.f; //底图 self.baseImageView = [[UIImageView alloc]initWithFrame:CGRectMake(20, 20, width, width)]; [_baseImageView setImage:[

网页设计中热门的css和js酷炫动画效果

最近在网站和博客上能发现使用各种各样很帮效果的动画效果.CodyHouse介绍了这些CSS和Javas cript的编码教程. 因为每个文件都可以整套下载,所以马上就可以使用. 固定背景效果 →效果页 适用的浏览器:Chrome,Safari,Firefox,Opera,IE9+ 在Section和div垂直配置的长页面中,把背景固定,像卷帘被提起似的滚动. 产品展示滑块 →效果页 适用的浏览器:Chrome,Safari,Firefox,Opera,IE9+ 把配置卡片状的各个产品,用很棒的动

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

其实就是在显示菜单栏时,有个动画的效果.代码比较简单,下面进行说明. 1.效果图如下,手机上查看效果更佳 2.代码实现,这里只讲解动画效果的实现,具体代码可在源代码中查看 <1> 先定义一个CanvasTransformer接口对象,这个接口是在slidingmenu_library类库中封装好的 private CanvasTransformer mTransformer; <2> 然后再实例化此接口,重写接口中的方法,例如示例1中的方法: /** * transformCanv

【Android的从零单排开发日记】之入门篇(十六)——Android的动画效果

      什么是动画,动画的本质是通过连续不断地显示若干图像来产生“动”起来的效果.比如说一个移动的动画,就是在一定的时间段内,以恰当的速率(起码要12帧/秒以上,才会让人产生动起来的错觉)每隔若干时间在屏幕上更新一次位置.游戏中的动画效果也是由此而来.同样还有其他属性变更所引起的动画效果,从数学的角度来看,包括:(1)平移(2)旋转(3)缩放(4)透明度.当然这些属性可以组合起来使用,来达到更绚丽的画面.但是不论什么样的组合方式,我们都可以统一用Matirx运算来实现,从技术实现的角度来讲,

运动曲线提升CSS动画效果

原文链接 译文\译者鞠大宝 先有UI动画,然后才会有好的UI动画.好的动画会让人惊叹“哇哦!”——因为页面看上去很流畅.很漂亮,最重要的是,自然,一点都不会让人觉得不和谐或者僵硬死板.如果你经常逛Dribbble或者 UpLabs这类网站的话,你就会明白我在说什么了. 一些极好的拓展阅读资源: ·SVG和CSS的路径剪辑动画 ·若干实用的动画技术 ·使用SVG手绘动画 ·新的网页动画API 既然有这么多天才设计师创造了如此漂亮的动画,自然是任何开发者都会想要在自己的项目中引进这些效果.如今,CS

动画效果:Animation

先创建一个图片imageView self.imageView =[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tara4.jpg"]]; self.imageView.frame =CGRectMake(85, 400, 200, 200); self.imageView.layer.cornerRadius =100; self.imageView.layer.masksToBounds=YES; [self.vi

风火轮 – 动画效果

风火轮越来越有广告范,之前实现的素材导入功能已能解决50%的用户需求,即可以拖入现成的动画.视频及图片素材,效果见QQ空间之前的某篇日志. 从进化发展角度来看,现在的很多产品,纯硬件的竞争已是薄利见血,软件功能提升才是王道. 所以,软件实现得加强.电子黑板如此,风火轮也如此. 准备实现动画效果. 闭门造车是白手起家的最脑残做法,所以先放眼成熟产品,看哪些功能与UI可以借鉴. 做素材,一般会选取FLASH.Photoshop,而动画效果,PPT是大家耳熟能详的. 仔细研究一下,决定采用PPT的界面