title: Multiple draw requests dynamically iPhone
body: <p>I'm attempting to make guider/tip boxes for the iPhone as part of a tutorial framework i'm making.
  I've followed and combined two codes i've found here:
  (http://stackoverflow.com/questions/6049682/iphone-how-to-make-a-tip-balloon-programmatically/6052438#6052438 ) and another (cant find the link but pretty sure the code supplier was Brad Larson (cheers dude!)) to make a working but limited framework</p>
  
  <p>The idea:
  A developer can import the completed files, instantiate what 'direction' arrow they want, set the co ordinates and text and assign it to whatever layer/array/setup they want</p>
  
  <p>The problems:
  1. I can only get the arrow to point upwards but needs to be changeable. I've gone through the code and messed around with it but my fundamental knowledge of CG is quite low.
  2. If I try to add additional methods they all need to be called from drawRect so any alternatives called at the same time, which I cant have
  3. Probably some general misunderstandings of core graphics is hindering as well.</p>
  
  <p>Code bits so far (I can post the whole code but its a bit long)
  In my main view controller i declare an instance of the UIView to draw it when a button is pressed</p>
  
  <pre><code>(in mainViewController.m)
  
  TipBallon *textExample = [[TipBallon alloc] initAtPoint:CGPointMake(50.0f, 50.0f) withText:
                            @"You are hearing me talk"];
  </code></pre>
  
  <p>And the TipBallon UIView:</p>
  
  <pre><code>- (void)drawRect:(CGRect)rect {
  [super drawRect:rect];
  CGContextRef contextRef = UIGraphicsGetCurrentContext();
  [self drawOutlineInContext:contextRef];
  [self drawTextInContext:contextRef];
  }
  
  - (id)initAtPoint:(CGPoint)point withText:(NSString *)string {
  CGSize size = [string sizeWithFont:[UIFont systemFontOfSize:kFontSize]
                   constrainedToSize:CGSizeMake(kMaxWidth, kMaxHeight)
                       lineBreakMode:UILineBreakModeWordWrap];
  CGRect rect = CGRectMake(point.x, point.y, size.width+kPaddingWidth*2.0f,
                           size.height+kPaddingHeight*2.0f+kArrowSize);
  if ((self = [super initWithFrame:rect])) {
      self.text = string;
      UIColor *clearColor = [[UIColor alloc] initWithWhite:0.0f alpha:0.0f];
      self.backgroundColor = clearColor;
      [clearColor release];
  }
  return self;
  }
  
  
  
  - (void)drawOutlineInContext:(CGContextRef)context {
  CGFloat HEIGHTOFPOPUPTRIANGLE = 15;
  CGFloat WIDTHOFPOPUPTRIANGLE = 30;
  CGFloat borderRadius = 7;
  CGFloat strokeWidth = 2;
  CGRect currentFrame = self.bounds;
  
  CGContextSetLineJoin(context, kCGLineJoinRound);
  CGContextSetLineWidth(context, strokeWidth);
  CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); 
  CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
  
  // Draw and fill the bubble
  CGContextBeginPath(context);
  CGContextMoveToPoint(context, borderRadius + strokeWidth + 0.5f, strokeWidth + HEIGHTOFPOPUPTRIANGLE + 0.5f);
  CGContextAddLineToPoint(context, round(currentFrame.size.width / 2.0f - WIDTHOFPOPUPTRIANGLE / 2.0f) + 0.5f, HEIGHTOFPOPUPTRIANGLE + strokeWidth + 0.5f);
  CGContextAddLineToPoint(context, round(currentFrame.size.width / 2.0f) + 0.5f, strokeWidth + 0.5f);
  CGContextAddLineToPoint(context, round(currentFrame.size.width / 2.0f + WIDTHOFPOPUPTRIANGLE / 2.0f) + 0.5f, HEIGHTOFPOPUPTRIANGLE + strokeWidth + 0.5f);
  CGContextAddArcToPoint(context, currentFrame.size.width - strokeWidth - 0.5f, strokeWidth + HEIGHTOFPOPUPTRIANGLE + 0.5f, currentFrame.size.width - strokeWidth - 0.5f, currentFrame.size.height - strokeWidth - 0.5f, borderRadius - strokeWidth);
  CGContextAddArcToPoint(context, currentFrame.size.width - strokeWidth - 0.5f, currentFrame.size.height - strokeWidth - 0.5f, round(currentFrame.size.width / 2.0f + WIDTHOFPOPUPTRIANGLE / 2.0f) - strokeWidth + 0.5f, currentFrame.size.height - strokeWidth - 0.5f, borderRadius - strokeWidth);
  CGContextAddArcToPoint(context, strokeWidth + 0.5f, currentFrame.size.height - strokeWidth - 0.5f, strokeWidth + 0.5f, HEIGHTOFPOPUPTRIANGLE + strokeWidth + 0.5f, borderRadius - strokeWidth);
  CGContextAddArcToPoint(context, strokeWidth + 0.5f, strokeWidth + HEIGHTOFPOPUPTRIANGLE + 0.5f, currentFrame.size.width - strokeWidth - 0.5f, HEIGHTOFPOPUPTRIANGLE + strokeWidth + 0.5f, borderRadius - strokeWidth);
  CGContextClosePath(context);
  CGContextDrawPath(context, kCGPathFillStroke);
  
  - (void)drawTextInContext:(CGContextRef)context {
  CGRect rect = self.bounds;
  rect.origin.x += kPaddingWidth;
  rect.origin.y += kPaddingHeight + kArrowSize;
  rect.size.width -= kPaddingWidth*2.0f;
  rect.size.height -= kPaddingHeight*2.0f;
  
  CGContextSetGrayFillColor(context, 0.0f, 1.0f); // black text
  [text drawInRect:rect withFont:[UIFont systemFontOfSize:kFontSize]
     lineBreakMode:UILineBreakModeWordWrap];
  }
  
  @end
  </code></pre>
  
  <p>So as I said earlier, if I make several versions of current method that draws the box with the arrow upwards, i'll have to add it to the drawRect method and then they all get called at the same time.
  The only course of action I can see is to make several different classes, one for each arrow direction but thats ridiculously messy.
  If anyone has any ideas on how to get around this i'd appreciate it muchly</p>