0

我正在尝试将 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];


    }
  }
}

那里有调用动作方法从颜色选择器获取变量的方法

- (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 事件的实例方法上,还有其他更有效的方法吗?

4

1 回答 1

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]吗?

于 2014-01-16T05:01:16.360 回答