Nick
Nick

Reputation: 8493

UIControl for a Needle Gauge aka Google O Meter

For those times when a UISlider just isn't fun enough I was thinking I'd work up a custom UIControl to do something similar to a Google O Meter from the google chart API on iOS.

Here's an example of what I'm talking about visually. My goal would be to enable touch manipulation of the needle and easy customization of the range labels and coloring gradients. The Google Charts API is a great inspiration:

Before I re-invent the wheel is anyone aware of an existing effort I could leverage good sample code with something like this or project I could contribute too?

Thanks for any pointers.

Upvotes: 2

Views: 836

Answers (1)

Sriram C
Sriram C

Reputation: 56

I have implemented a GaugeView as a child of UIView and added the code to draw the gauge in the drawRect method. Nothing fancy but may be helpful to start

 - (void)drawRect:(CGRect)rect {

     [super drawRect:rect];
     CGRect parentViewBounds = self.bounds;
     CGFloat x = CGRectGetWidth(parentViewBounds)/2;
     CGFloat y = CGRectGetHeight(parentViewBounds);
     CGFloat radius = y;
     CGFloat percent_angle = _progress * M_PI;

     CGContextRef ctx = UIGraphicsGetCurrentContext();
     CGContextBeginPath(ctx);

     // Add path
     CGFloat m2_x = radius * (1.0 - 0.9*cos(percent_angle));
     CGFloat m2_y = radius * (1.0 - 0.9*sin(percent_angle));      

     CGContextBeginPath(ctx);
     CGContextAddArc(ctx, x, y, radius, M_PI, 0, 0);
     CGContextAddLineToPoint(ctx, x + 0.1*radius, y);
     CGContextAddArc(ctx, x, y, 0.1*radius, 0, M_PI, 1);
     CGContextClosePath(ctx);
     CGContextSetFillColorWithColor(ctx,[UIColor whiteColor].CGColor);
     CGContextFillPath(ctx);

     CGContextBeginPath(ctx);
     CGContextMoveToPoint(ctx, m2_x, m2_y);
     CGContextAddArc(ctx, x, y, 0.9*radius, M_PI + percent_angle, M_PI, 1);
     CGContextAddLineToPoint(ctx, 0.8*radius, y);
     CGContextSetStrokeColorWithColor(ctx,self.fillColor.CGColor);
     CGContextAddArc(ctx, x, y, 0.2*radius, M_PI, M_PI + percent_angle, 0);
     CGContextClosePath(ctx);
     CGContextStrokePath(ctx);

     CGContextBeginPath(ctx);
     CGContextMoveToPoint(ctx, m2_x, m2_y);
     CGContextSetFillColorWithColor(ctx,self.fillColor.CGColor);
     CGContextAddArc(ctx, x, y, 0.9*radius, M_PI + percent_angle, M_PI, 1);
     CGContextAddLineToPoint(ctx, 0.8*radius, y);
     CGContextAddArc(ctx, x, y, 0.2*radius, M_PI, M_PI + percent_angle, 0);
     CGContextClosePath(ctx);
     CGContextFillPath(ctx);

    /* CGContextBeginPath(ctx);
     CGContextAddArc(ctx, x, y, radius, M_PI, 0, 0);
     CGContextAddLineToPoint(ctx, x + 0.1*radius, y);
     CGContextAddArc(ctx, x, y, 0.1*radius, 0, M_PI, 1);
     CGContextClosePath(ctx);
     CGContextSetStrokeColorWithColor(ctx,[self.strokeColor CGColor]);
     CGContextStrokePath(ctx);*/

     for(int i = 0; i < 100; i++)
     {
         CGFloat angle =M_PI * 0.01 * i;
         CGFloat l1_x = radius * (1.0 - 0.98*cos(angle));
         CGFloat l1_y = radius * (1.0 - 0.98*sin(angle));
         if(i%10 == 0)
         {
             l1_x = radius * (1.0 - 0.9*cos(angle));
             l1_y = radius * (1.0 - 0.9*sin(angle));
         }
         else if(i%5 == 0)
         {
             l1_x = radius * (1.0 - 0.95*cos(angle));
             l1_y = radius * (1.0 - 0.95*sin(angle));             
         }

         CGFloat l2_x = radius * (1.0 - cos(angle));
         CGFloat l2_y = radius * (1.0 - sin(angle)); 
         CGContextMoveToPoint(ctx, l1_x, l1_y);
         CGContextSetLineWidth(ctx, 1.0);
         CGContextAddLineToPoint(ctx, l2_x, l2_y);
         CGContextSetStrokeColorWithColor(ctx,[self.strokeColor CGColor]);
         CGContextStrokePath(ctx);
     }

     CGFloat n1_x = radius * (1.0 - 0.1*cos(percent_angle));
     CGFloat n1_y = radius * (1.0 - 0.1*sin(percent_angle));
     CGFloat n2_x = radius * (1.0 - cos(percent_angle));
     CGFloat n2_y = radius * (1.0 - sin(percent_angle)); 
     CGContextMoveToPoint(ctx, n1_x, n1_y);
     CGContextSetLineWidth(ctx, 4.0);
     CGContextAddLineToPoint(ctx, n2_x, n2_y);
     CGContextSetStrokeColorWithColor(ctx,[self.needleColor CGColor]);
     CGContextStrokePath(ctx);

 }

Upvotes: 4

Related Questions