在UIRotationGestureRecognizer中,我将执行一次drawCircleView操作。
但是此动作最多应在一秒钟内开始10次。
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateContainerView:)];
rotation.delegate = self;
[_containerView addGestureRecognizer:rotation];
- (void)rotateContainerView:(UIRotationGestureRecognizer*)sender
{
static CGFloat initialScale;
if (sender.state == UIGestureRecognizerStateBegan) {
initialScale = (_Ro + 0.1)*-1;
_Rotation=0;
}
_Ro = (sender.rotation*-1);
sleep(.1);
[self drawCircleView];
}
我已经测试了以下
sleep(0.1);
[NSThread sleepForTimeInterval:.1];
NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]];
[NSThread sleepForTimeInterval:.1];
但是所有这些似乎都排在了队列中。
我如何在没有查询队列的情况下做到这一点?
完整代码
//
// CLHoleEffect.m
//
// Created by Kevin Siml - Appzer.de on 2013/10/23.
// Copyright (c) 2013 Appzer.de. All rights reserved.
//
#import "CLSwirlEffect.h"
#import "UIView+Frame.h"
@interface CLSwirlCircle : UIView
@property (nonatomic, strong) UIColor *color;
@end
@interface CLSwirlEffect()
<UIGestureRecognizerDelegate>
@end
@implementation CLSwirlEffect
{
UIView *_containerView;
UIView *_container;
CLSwirlCircle *_circleView;
UILabel* circleLabel;
CGFloat _X;
CGFloat _Y;
CGFloat _R;
CGFloat _Ro;
CGFloat _Rotation;
}
#pragma mark-
+ (NSString*)defaultTitle
{
return NSLocalizedStringWithDefaultValue(@"CLSwirlEffect_DefaultTitle", nil, [CLImageEditorTheme bundle], @"Swirl", @"");
}
+ (BOOL)isAvailable
{
return ([UIDevice iosVersion] >= 5.0);
}
- (id)initWithSuperView:(UIView*)superview imageViewFrame:(CGRect)frame toolInfo:(CLImageToolInfo *)info
{
self = [super initWithSuperView:superview imageViewFrame:frame toolInfo:info];
if(self){
_containerView = [[UIView alloc] initWithFrame:frame];
[superview addSubview:_containerView];
_X = 0.5;
_Y = 0.5;
_R = 0.5;
_Ro = 0.5;
[self setUserInterface];
}
return self;
}
- (void)cleanup
{
[_containerView removeFromSuperview];
}
- (UIImage*)applyEffect:(UIImage*)image
{
CGFloat R = (_R + 0.1);
GPUImageSwirlFilter *stillImageFilter = [[GPUImageSwirlFilter alloc] init];
[stillImageFilter setAngle: _Ro];
[stillImageFilter setRadius:R];
[stillImageFilter setCenter:CGPointMake(_X,_Y)];
UIImage *quickFilteredImage = [stillImageFilter imageByFilteringImage:image];
return quickFilteredImage;
}
#pragma mark-
- (void)setUserInterface
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapContainerView:)];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panContainerView:)];
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchContainerView:)];
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateContainerView:)];
pan.maximumNumberOfTouches = 1;
tap.delegate = self;
pan.delegate = self;
pinch.delegate = self;
rotation.delegate = self;
[_containerView addGestureRecognizer:tap];
[_containerView addGestureRecognizer:pan];
[_containerView addGestureRecognizer:pinch];
[_containerView addGestureRecognizer:rotation];
_circleView = [[CLSwirlCircle alloc] init];
_circleView.backgroundColor = [UIColor clearColor];
_circleView.color = [UIColor whiteColor];
[_containerView addSubview:_circleView];
[self drawCircleView];
}
#define DEGREES_TO_RADIANS(x) (M_PI * x / 180.0)
- (void)drawCircleView
{
CGFloat R = MIN(_containerView.width, _containerView.height) * (_R + 0.1) * 1.2;
_circleView.width = R;
_circleView.height = R;
_circleView.center = CGPointMake(_containerView.width * _X, _containerView.height * _Y);
[_circleView setNeedsDisplay];
[self.delegate effectParameterDidChange:self];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
// if the gesture recognizers are on different views, don't allow simultaneous recognition
if (gestureRecognizer.view != otherGestureRecognizer.view)
return NO;
// if either of the gesture recognizers is the long press, don't allow simultaneous recognition
if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]])
return NO;
return YES;
}
- (void)tapContainerView:(UITapGestureRecognizer*)sender
{
CGPoint point = [sender locationInView:_containerView];
_X = MIN(1.0, MAX(0.0, point.x / _containerView.width));
_Y = MIN(1.0, MAX(0.0, point.y / _containerView.height));
[self drawCircleView];
if (sender.state == UIGestureRecognizerStateEnded){
[self.delegate effectParameterDidChange:self];
}
}
- (void)panContainerView:(UIPanGestureRecognizer*)sender
{
CGPoint point = [sender locationInView:_containerView];
_X = MIN(1.0, MAX(0.0, point.x / _containerView.width));
_Y = MIN(1.0, MAX(0.0, point.y / _containerView.height));
[self drawCircleView];
if (sender.state == UIGestureRecognizerStateEnded){
//[self.delegate effectParameterDidChange:self];
}
}
- (void)pinchContainerView:(UIPinchGestureRecognizer*)sender
{
static CGFloat initialScale;
if (sender.state == UIGestureRecognizerStateBegan) {
initialScale = (_R + 0.1);
}
_R = MIN(1.1, MAX(0.1, initialScale * sender.scale)) - 0.1;
[self drawCircleView];
if (sender.state == UIGestureRecognizerStateEnded){
// [self.delegate effectParameterDidChange:self];
}
}
- (void)rotateContainerView:(UIRotationGestureRecognizer*)sender
{
static CGFloat initialScale;
if (sender.state == UIGestureRecognizerStateBegan) {
initialScale = (_Ro + 0.1)*-1;
_Rotation=0;
}
_Ro = (sender.rotation*-1);
[self drawCircleView];
if (sender.state == UIGestureRecognizerStateEnded){
// [self.delegate effectParameterDidChange:self];
}
}
@end
#pragma mark- UI components
@implementation CLSwirlCircle
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self setNeedsDisplay];
}
- (void)setCenter:(CGPoint)center
{
[super setCenter:center];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rct = self.bounds;
rct.origin.x += 1;
rct.origin.y += 1;
rct.size.width -= 2;
rct.size.height -= 2;
CGContextSetStrokeColorWithColor(context, self.color.CGColor);
CGContextStrokeEllipseInRect(context, rct);
self.alpha = 1;
[UIView animateWithDuration:kCLEffectToolAnimationDuration
delay:1
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.alpha = 0;
}
completion:^(BOOL finished) {
}
];
}
@end
最佳答案
为了限制该方法, rotationContainerView:,在一秒钟内被调用最多不超过十次,您可以给第一个调用加上时间戳,并比较每个后续调用的时间戳,仅当调用时间戳大于最后一个调用时间戳加上时,方法才能完成0.1秒
添加类型的属性NSDate -
@property (nonatomic, strong) NSDate *lastCall;
然后将 rotationContainerView:修改为类似以下内容-
- (void)rotateContainerView:(UIRotationGestureRecognizer*)sender
{
static CGFloat initialScale;
NSDate *nowCall = [NSDate date];// timestamp
if (sender.state == UIGestureRecognizerStateBegan) {
lastCall = nowCall;
initialScale = (_Ro + 0.1)*-1;
_Rotation=0;
_Ro = (sender.rotation*-1);
[self drawCircleView];
}
else {
if ([nowCall timeIntervalSinceDate:lastCall] > 0.1) {
_Ro = (sender.rotation*-1);
[self drawCircleView];
lastCall = nowCall;
}
}
}