views:

125

answers:

1

I'm implementing some charts with some user interactions, like long-pressing to view the full data under the finger, two fingers to draw a line, and other stuff.

For a start, how would I implement the kind of interaction the iphone stocks app does in the landscape mode of the price chart?

Manipulate a CALayer for the yellow vertical line and the yellow dot? Are those coming from images or rendered? Use a UIView (or UIImageView) instead? Or render them in drawRect?

A: 

I think it's really just an implementation detail so it's up to you how to do it. I would guess that they're doing everything in -drawRect, however, you could implement it with Core Animation layers if you wanted to.

If you're already drawing the graph with -drawRect, then it would make sense to stick with that, however, if you just want to overlay layers for the yellow dot and the vertical yellow line you can just use regular CALayer s and change their position in response to -touchesMoved.

// Create a line layer with a 1px width and yellow bg
CALayer *lineLayer = [CALayer layer];
[lineLayer setBounds:CGRectMake(0.0f, 0.0f, 1.0f, parentViewHeight)];
[lineLayer setPosition:CGPointMake(currentX, parentViewHeight/2.0f)];
[lineLayer setBackgroundColor:[[UIColor yellowColor] CGColor]];
[[parentView layer] addSublayer:lineLayer];

// Create a dot layer with the contents set to a CGImageRef
UIImage *dotImage = [UIImage imageNamed:@"yellowdot.png"];
CALayer *dotLayer = [CALayer layer];
[dotLayer setBounds:CGRectMake(0.0f, 0.0f, [dotImage size].width, 
                                               [dotImage size].height)];
[dotLayer setPosition:[lineLayer position]];
[dotLayer setContents:[dotImage CGImage]];
[[parentView layer] addSublayer:dotLayer];

You'll need to make these layers ivars of your class so that when you receive your touch events, you can update their positions.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
{
  CGPoint current = [[touches anyObject] locationInView:parentView];
  [lineLayer setPosition:CGPointMake(current.x, [lineLayer position].y)];
  [dotLayer setPosition:CGPointMake(current.x, [self yForStockPriceAtPoint:current])];

  [super touchesMoved:touches withEvent:event];
}
Matt Long