从 UITouch 对象调用 UIGestureRecognizer
Posted
技术标签:
【中文标题】从 UITouch 对象调用 UIGestureRecognizer【英文标题】:Calling UIGestureRecognizer from UITouch object 【发布时间】:2014-01-16 00:16:26 【问题描述】:我正在尝试将 Gesture 与 UITouch 对象相关联,因为我需要通过目标操作方法传递数据。
我实现了一些东西,但效率低下,它得到了 100% 的 CPU 处理,可能是因为它编码不正确。
我的 UITouch 事件的实例方法调用了 UIPangesture
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
return YES;
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:@selector(handlePan:)];
[self addGestureRecognizer: panGesture];
UIPAnGestureRecognizer 有我的实例方法
- (IBAction)handlePan:(UIPanGestureRecognizer *)event
if (event.numberOfTouches==1)
CGPoint lastPoint = [event locationOfTouch: event.numberOfTouches - 1 inView: event.view];
CGRect bounds = self.bounds;
CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
CGPoint delta = CGPointMake(lastPoint.x - center.x, lastPoint.y - center.y);
CGFloat angle = (delta.y == 0 ? delta.x >= 0 ? 0 : M_PI : atan2(delta.y, delta.x));
angle = fmod(angle, M_PI * 2.0);
angle += angle >= 0 ? 0 : M_PI * 2.0;
UIColor *color = [UIColor colorWithHue: angle / (M_PI * 2.0) saturation:1. brightness:1. alpha:1];
if ([color getRed: &r green: &g blue:&b alpha: &a])
rValue = r;
gValue = g;
bValue = b;
[self setNeedsDisplay];
[self sendActionsForControlEvents:UIControlEventValueChanged];
[self updateLabels];
还有调用action方法从颜色选择器中获取变量的方法
- (void)setup:(CsoundObj *)csoundObj
NSLog(@"Color value - R : %f G : %f : B %f", rValue, gValue, bValue);
channelPtrR = [csoundObj getInputChannelPtr:@"mix" channelType:CSOUND_CONTROL_CHANNEL];
channelPtrG = [csoundObj getInputChannelPtr:@"pitch" channelType:CSOUND_CONTROL_CHANNEL];
channelPtrB = [csoundObj getInputChannelPtr:@"c" channelType:CSOUND_CONTROL_CHANNEL];
cachedValueR = rValue;
cachedValueG = gValue;
cachedValueB = bValue;
self.cacheDirty = YES;
[self addTarget:self action:@selector(updateValueCache:) forControlEvents:UIControlEventValueChanged];
- (void)updateValueCache:(id)sender
cachedValueR = ((CustomView*)sender).rValue;
cachedValueG = ((CustomView*)sender).gValue;
cachedValueB = ((CustomView*)sender).bValue;
self.cacheDirty = YES;
- (void)updateValuesToCsound
if (self.cacheDirty)
*channelPtrR = cachedValueR;
*channelPtrG = cachedValueG;
*channelPtrB = cachedValueB;
self.cacheDirty = NO;
- (void)updateValuesFromCsound
- (void)cleanup
[self removeTarget:self action:@selector(updateValueCache:) forControlEvents:UIControlEventValueChanged];
我知道问题在于调用 UIPangesture 的 UITouch 事件的实例方法,还有其他更有效的方法吗?
【问题讨论】:
【参考方案1】:我认为您过于频繁地调用这部分代码:
CGPoint lastPoint = [event locationOfTouch: event.numberOfTouches - 1 inView: event.view];
CGRect bounds = self.bounds;
CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
CGPoint delta = CGPointMake(lastPoint.x - center.x, lastPoint.y - center.y);
CGFloat angle = (delta.y == 0 ? delta.x >= 0 ? 0 : M_PI : atan2(delta.y, delta.x));
angle = fmod(angle, M_PI * 2.0);
angle += angle >= 0 ? 0 : M_PI * 2.0;
UIColor *color = [UIColor colorWithHue: angle / (M_PI * 2.0) saturation:1. brightness:1. alpha:1];
if ([color getRed: &r green: &g blue:&b alpha: &a])
rValue = r;
gValue = g;
bValue = b;
[self setNeedsDisplay];
[self sendActionsForControlEvents:UIControlEventValueChanged];
[self updateLabels];
您可能会在没有变化或几乎没有变化时调用它。您可以做两件事来减少调用次数。您可以像这样测试角度的显着变化:
//class property
@property (nonatomic, assign) CGFloat lastAngle;
//In your code
CGFloat deltaAngle = fabs(self.lastAngle - angle)
if (deltaAngle > 0.5) //select whatever delta works best
angle += angle >= 0 ? 0 : M_PI * 2.0;
UIColor *color = [UIColor colorWithHue: angle / (M_PI * 2.0) saturation:1. brightness:1. alpha:1];
if ([color getRed: &r green: &g blue:&b alpha: &a])
rValue = r;
gValue = g;
bValue = b;
[self sendActionsForControlEvents:UIControlEventValueChanged];
[self updateLabels];
[self setNeedsDisplay];
或者您可以像这样测试自上次更新以来的时间:
//class property
@property (nonatomic, retain) NSDate *lastTime;
//set it when the view loads
self.lastTime = [NSDate date];
//In your code
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:lastdate];
self.lastTime = [NSDate date];
if (interval > 0.05) //select whatever time interval works best
angle += angle >= 0 ? 0 : M_PI * 2.0;
UIColor *color = [UIColor colorWithHue: angle / (M_PI * 2.0) saturation:1. brightness:1. alpha:1];
if ([color getRed: &r green: &g blue:&b alpha: &a])
rValue = r;
gValue = g;
bValue = b;
[self sendActionsForControlEvents:UIControlEventValueChanged];
[self updateLabels];
[self setNeedsDisplay];
另外,您确定需要 [self setNeedsDisplay]
吗?
【讨论】:
非常感谢 HalR,你说得对,我在调用 setNeedsDisplay 但我不需要它,现在它运行得非常好。以上是关于从 UITouch 对象调用 UIGestureRecognizer的主要内容,如果未能解决你的问题,请参考以下文章
如何从 - (void)touchesEnded:withEvent: 获取 UITouch 位置的 UIView 对象?