使用 CPBPressureTouchGestureRecognizer 检测敲击压力强度 [英] Tap pressure strength detection using CPBPressureTouchGestureRecognizer

查看:22
本文介绍了使用 CPBPressureTouchGestureRecognizer 检测敲击压力强度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用一个 UIButton 效果很好:

it's working great with one UIButton:

 – (void) viewDidLoad {
[super viewDidLoad];

CPBPressureTouchGestureRecognizer* recognizer = [[CPBPressureTouchGestureRecognizer alloc] initWithTarget:self action:@selector(A_button:)];
[A_button addGestureRecognizer: recognizer];
[recognizer release];
}


- (void) A_button: (CPBPressureTouchGestureRecognizer*) recognizer {
[pan_A setGain:recognizer.pressure];
[pan_A] play;
}

我尝试使用更多,但只有第二个有效:

i tried to use more but only the second one is working:

- (void) viewDidLoad {
[super viewDidLoad];
CPBPressureTouchGestureRecognizer* recognizer1 = [[CPBPressureTouchGestureRecognizer alloc] initWithTarget:self action:@selector(A_button:)];
[A_button addGestureRecognizer: recognizer1];

CPBPressureTouchGestureRecognizer* recognizer2 = [[CPBPressureTouchGestureRecognizer alloc] initWithTarget:self action:@selector(B_button:)];
[B_button addGestureRecognizer: recognizer1];
[recognizer1 release];
[recognizer2 release];
}

- (void) A_button: (CPBPressureTouchGestureRecognizer*) recognizer1 {
[pan_A setGain:recognizer1.pressure];
[pan_A] play;
}

- (void) B_button: (CPBPressureTouchGestureRecognizer*) recognizer1 {
[pan_B setGain:recognizer2.pressure];
[pan_B] play;
}

我怎样才能让两者都工作?

how can i get both to work?

推荐答案

CPBPressureTouchGestureRecognizer 仅支持对 UIAccelerometer 的委托模型执行的单个实例.这是一个支持多个实例的更好版本.

The CPBPressureTouchGestureRecognizer only supported a single instance of itself do to the delegate model of the UIAccelerometer. Here is a better version that supports multiple instances.

//  CPBPressureTouchGestureRecognizer.h
//  PressureSensitiveButton

#import <UIKit/UIKit.h>

#define CPBPressureNone         0.0f
#define CPBPressureLight        0.3f
#define CPBPressureMedium       0.4f
#define CPBPressureHard         0.6f
#define CPBPressureInfinite     2.0f

@interface CPBPressureTouchGestureRecognizer : UIGestureRecognizer {
    @public
    float pressure;
    float minimumPressureRequired;
    float maximumPressureRequired;

    @private
    float pressureValues[50];
    uint currentPressureValueIndex;
    uint setNextPressureValue;
}

@property (readonly, assign) float pressure;
@property (readwrite, assign) float minimumPressureRequired;
@property (readwrite, assign) float maximumPressureRequired;

@end

//  CPBPressureTouchGestureRecognizer.m

#import <UIKit/UIGestureRecognizerSubclass.h>
#import "CPBPressureTouchGestureRecognizer.h"
#import "CPBAcceleromterDelegate.h"

#define kUpdateFrequency            60.0f
#define KNumberOfPressureSamples    3

@interface CPBPressureTouchGestureRecognizer (private)
    - (void)setup;
@end

@implementation CPBPressureTouchGestureRecognizer
@synthesize pressure, minimumPressureRequired, maximumPressureRequired;

- (id)initWithTarget:(id)target action:(SEL)action {
    self = [super initWithTarget:target action:action];
    if (self != nil) {
       [self setup];
    }
    return self;
}

- (id)init {
    self = [super init];
    if (self != nil) {
        [self setup];
    }
    return self;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

- (void)setup {
    minimumPressureRequired = CPBPressureNone;
    maximumPressureRequired = CPBPressureInfinite;
    pressure = CPBPressureNone;

    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:0.001f / kUpdateFrequency];
    [[UIAccelerometer sharedAccelerometer] setDelegate:[CPBAcceleromterDelegate sharedCPBAcceleromterDelegate]];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(accelerateNotification:) name:CPB_ACCELERATION_EVENT object:nil];
}

#pragma -
#pragma UIAccelerometerDelegate methods

- (void)accelerateNotification:(NSNotification *)notification {

    UIAcceleration *acceleration = [[CPBAcceleromterDelegate sharedCPBAcceleromterDelegate] acceleration];

    int sz = (sizeof pressureValues) / (sizeof pressureValues[0]);

    // set current pressure value
    pressureValues[currentPressureValueIndex%sz] = acceleration.z;

    if (setNextPressureValue > 0) {

        // calculate average pressure
        float total = 0.0f;
        for (int loop=0; loop<sz; loop++) total += pressureValues[loop]; 
        float average = total / sz;

        // start with most recent past pressure sample
        if (setNextPressureValue == KNumberOfPressureSamples) {
            float mostRecent = pressureValues[(currentPressureValueIndex-1)%sz];
            pressure = fabsf(average - mostRecent);
        }

        // caluculate pressure as difference between average and current acceleration
        float diff = fabsf(average - acceleration.z);
        if (pressure < diff) pressure = diff;
        setNextPressureValue--;

        if (setNextPressureValue == 0) {
            if (pressure >= minimumPressureRequired && pressure <= maximumPressureRequired)
                self.state = UIGestureRecognizerStateRecognized;
            else
                self.state = UIGestureRecognizerStateFailed;
        }
    }

    currentPressureValueIndex++;
}

#pragma -
#pragma UIGestureRecognizer subclass methods

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    setNextPressureValue = KNumberOfPressureSamples;
    self.state = UIGestureRecognizerStatePossible;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    self.state = UIGestureRecognizerStateFailed;
}

- (void)reset {
    pressure = CPBPressureNone;
    setNextPressureValue = 0;
    currentPressureValueIndex = 0;
}

@end


//
//  CPBAcceleromterDelegate.h
//  iPan
//
//  Created by Anthony Picciano on 1/25/12.
//  Copyright (c) 2012 Crispin Porter + Bogusky. All rights reserved.
//

#import <Foundation/Foundation.h>
#define CPB_ACCELERATION_EVENT @"accellerationEvent"

@interface CPBAcceleromterDelegate : NSObject <UIAccelerometerDelegate>

@property (nonatomic, retain) UIAcceleration *acceleration;

+ (CPBAcceleromterDelegate *)sharedCPBAcceleromterDelegate;

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration;

@end


//
//  CPBAcceleromterDelegate.m
//  iPan
//
//  Created by Anthony Picciano on 1/25/12.
//  Copyright (c) 2012 Crispin Porter + Bogusky. All rights reserved.
//

#import "CPBAcceleromterDelegate.h"
#include "SynthesizeSingleton.h"

@implementation CPBAcceleromterDelegate
@synthesize acceleration;

SYNTHESIZE_SINGLETON_FOR_CLASS(CPBAcceleromterDelegate)

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)newAcceleration
{
    self.acceleration = newAcceleration;
    [[NSNotificationCenter defaultCenter] postNotificationName:CPB_ACCELERATION_EVENT object:self];
}

@end


//
//  SynthesizeSingleton.h
//  CocoaWithLove
//
//  Created by Matt Gallagher on 20/10/08.
//  Copyright 2009 Matt Gallagher. All rights reserved.
//  http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html
//
//  Permission is given to use this source code file without charge in any
//  project, commercial or otherwise, entirely at your risk, with the condition
//  that any redistribution (in part or whole) of source code must retain
//  this copyright and permission notice. Attribution in compiled projects is
//  appreciated but not required.
//

#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) 

static classname *shared##classname = nil; 

+ (classname *)shared##classname 
{ 
@synchronized(self) 
{ 
if (shared##classname == nil) 
{ 
shared##classname = [[self alloc] init]; 
} 
} 

return shared##classname; 
} 

+ (id)allocWithZone:(NSZone *)zone 
{ 
@synchronized(self) 
{ 
if (shared##classname == nil) 
{ 
shared##classname = [super allocWithZone:zone]; 
return shared##classname; 
} 
} 

return nil; 
} 

- (id)copyWithZone:(NSZone *)zone 
{ 
return self; 
} 

- (id)retain 
{ 
return self; 
} 

- (NSUInteger)retainCount 
{ 
return NSUIntegerMax; 
} 

- (void)release 
{ 
} 

- (id)autorelease 
{ 
return self; 
}

这篇关于使用 CPBPressureTouchGestureRecognizer 检测敲击压力强度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆