码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-10-15 00:26:30      阅读:324      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   使用   ar   for   

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

bubuko.com,布布扣

效果图:

bubuko.com,布布扣

源码:

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是业界良心啊!以下是使用细节:

bubuko.com,布布扣

bubuko.com,布布扣

 

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

标签:style   blog   http   color   io   os   使用   ar   for   

原文地址:http://www.cnblogs.com/YouXianMing/p/4025160.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!