Вызов 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]?

Другие вопросы по тегам