Вызов UIGestureRecognizer из объекта UITouch
Я пытаюсь связать жест с объектом UITouch, потому что мне нужно передать данные через метод целевого действия.
Я что-то реализовал, но это неэффективно, он получает 100% процессорной обработки, вероятно, потому что он закодирован неправильно.
Есть мой метод экземпляра для события 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];
}
}
}
И там есть методы, которые вызывают метод действия для получения переменных из палитры цветов
- (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];
}
Я знаю, что проблема в методе экземпляра для события UITouch, которое вызывает UIPangesture, есть ли другой способ сделать это более эффективно?
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]
?