I've got this horizontal bar (rectangular area) that represents a voltage from 0 to 5V. If, for example, the voltage is 2V, the bar fills up to the 2V mark with the color green.
From 0-2.1V, the color of the area representing the voltage should be green. From 2.9-5V, the color should be red.
I want to make a color transition from 2.1-2.9 that goes from green to red. I've tried one solution that I got from another StackOverflow topic, but I don't like the results because there are too many colors in the spectrum that don't look like they belong.
Here is that solution (the 80 is for the range 2.90 - 2.10 = .80):
- (void)updateLayerProperties {
CGRect barRect = self.bounds;
barRect.size.width = (self.bounds.size.width * self.value)/3.5;
UIBezierPath *path = [UIBezierPath bezierPathWithRect:barRect];
self.barLayer.path = path.CGPath;
if (self.value >= 1.30 && self.value <= 1.70) {
self.barLayer.fillColor = [UIColor colorWithRed:((255 * (self.value - 1.00)) / 80)
green:((255 * (80 - (self.value - 1.00))) / 80)
blue:0
alpha:1.0].CGColor;
} else {
self.barLayer.fillColor = (self.value >= self.threshold) ? self.fullColor.CGColor : self.emptyColor.CGColor;
}
self.layer.borderWidth = self.borderWidth;
self.layer.borderColor = self.borderColor.CGColor;
self.layer.cornerRadius = 2.0f;
self.layer.masksToBounds = YES;
}
Originally, I just had 0-2.5V is green, 2.5-5V is red...but this looks bad to eye, so I'm trying this out.
Is there some type of animation to use instead of calculating colors based on value of voltage? Assuming the transition gap is the 2.1 - 2.9, the transition should know how to display the best colors between Green and Red. Thanks.
This should get you started:
//
// GradientBarView.h
//
// Created by Don Mag on 4/5/18.
//
#import <UIKit/UIKit.h>
@interface GradientBarView : UIView
@end
//
// GradientBarView.m
//
// Created by Don Mag on 4/5/18.
//
#import "GradientBarView.h"
@interface GradientBarView ()
@property (strong, nonatomic) CAGradientLayer *gradLayer;
@end
@implementation GradientBarView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
[self commonInit];
}
return self;
}
- (void)commonInit {
// instantiate the gradient layer
_gradLayer = [CAGradientLayer new];
// initial size
_gradLayer.frame = self.bounds;
// 4 colors, so we can have solid - gradient - solid
_gradLayer.colors = @[
(__bridge id)[UIColor greenColor].CGColor,
(__bridge id)[UIColor greenColor].CGColor,
(__bridge id)[UIColor redColor].CGColor,
(__bridge id)[UIColor redColor].CGColor,
];
// 0.0 -> 2.1 should be green
// 2.1 -> 2.9 should be a green-to-red gradient
// 2.9 -> 5.0 should be red
_gradLayer.locations = @[
@(0.0),
@(2.1 / 5.0),
@(2.9 / 5.0),
@(1.0)
];
// make it horizontal
_gradLayer.startPoint = CGPointMake(0.0, 0.5);
_gradLayer.endPoint = CGPointMake(1.0, 0.5);
// add the gradient layer
[self.layer addSublayer:_gradLayer];
}
- (void)layoutSubviews {
_gradLayer.frame = self.bounds;
}
@end
//
// GradBarViewController.h
//
// Created by Don Mag on 4/5/18.
//
#import <UIKit/UIKit.h>
@interface GradBarViewController : UIViewController
@end
//
// GradBarViewController.m
//
// Created by Don Mag on 4/5/18.
//
#import "GradBarViewController.h"
#import "GradientBarView.h"
@interface GradBarViewController ()
@property (strong, nonatomic) GradientBarView *gradBarView;
@end
@implementation GradBarViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// instantiate a GradientBarView
_gradBarView = [GradientBarView new];
// we'll use autolayout
_gradBarView.translatesAutoresizingMaskIntoConstraints = NO;
// add the view
[self.view addSubview:_gradBarView];
// center a 300 x 40 view
/* center horizontally to superview */
[NSLayoutConstraint constraintWithItem:_gradBarView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute: NSLayoutAttributeCenterX
multiplier:1.0
constant:0].active = YES;
/* center vertically to superview */
[NSLayoutConstraint constraintWithItem:_gradBarView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute: NSLayoutAttributeCenterY
multiplier:1.0
constant:0].active = YES;
/* Fixed width */
[NSLayoutConstraint constraintWithItem:_gradBarView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:300.0].active = YES;
/* Fixed Height */
[NSLayoutConstraint constraintWithItem:_gradBarView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:40.0].active = YES;
}
@end
Result (click the image to see it full-size):
I'll leave it up to you to look up how to mask the view so you're only showing X-number of points from the left.