3

I have a UIView subclass that moved around 'event's when the user touches them, using the following overridden method:

// In a custom UIView...

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint point = [[touches anyObject] locationInView:self];
    UIView *eventView = [self.ringOfEvents hitTest:point withEvent:event];
    for (EventView *e in self.events) {
        if (e == eventView) {
            event.position = point;
        }
    }
}

Why is it that when I make EventView a CALayer instead of UIView, the movement slows down to a creep? I can post that code too, but it is so similar that I don't think it is necessary.

I would think that abstracting to a lower level would speed up event handling, but I must be missing something.

By the way, either if *eventView is a subclass of UIView or CALayer, the position property is as follows:

- (void)setPosition:(CGPoint)pos {
    self.layer.position = pos;
}

- (CGPoint)position {
    return self.layer.position;
}

Not sure why I get a huge decrease in latency when using UIView as apposed to CALayer..

rich.e
  • 3,660
  • 4
  • 28
  • 44

2 Answers2

6

Most CALayer properties are changed with animation by default, so decrease in latency is probably caused by that.

You may want to disable animations when layer position is changed. Possible solutions are discussed for example in here and here

Community
  • 1
  • 1
Vladimir
  • 170,431
  • 36
  • 387
  • 313
  • 1
    Ah, that was definetely it; adding an `[NSNull null]` to the layer's `actions` dictionary for `position` brought the layer's movement latency back up to par with that of `UIView`'s, and then some.. thanks! – rich.e Oct 15 '11 at 05:41
2

This is due to implicit animations.

I've implemented a category method which removes implicit animation for givven keys and can be used like this

[view.layer setNullAsActionForKeys:@[@"bounds", @"position"]];

Implementation

@implementation CALayer (Extensions)

- (void)setNullAsActionForKeys:(NSArray *)keys
{
    NSMutableDictionary *dict = [self.actions mutableCopy];

    if(dict == nil)
    {
        dict = [NSMutableDictionary dictionaryWithCapacity:[keys count]];
    }

    for(NSString *key in keys)
    {
        [dict setObject:[NSNull null] forKey:key];
    }

    self.actions = dict;
}

@end
hfossli
  • 22,616
  • 10
  • 116
  • 130