Как рисовать линии на UIView

Я пытаюсь создать свой собственный контроль линейных графиков.

Я уже создал логику для преобразования данных (формат: дата - значение) в координаты, теперь мне просто нужно отобразить строки в представлении.

Вот мои примеры данных:

У меня есть UIView на моем контроле, и розетка:

@property (weak, nonatomic) IBOutlet UIView *iboChartsFieldView;

Итак, вот моя функция рисовать линии:

- (void)drawLine:(ChartPoint*)start endPoint:(ChartPoint *) end
{
UIGraphicsBeginImageContext(self.iboChartsFieldView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetLineWidth(context, 1.0f);
CGContextSetStrokeColorWithColor(context, [[UIColor darkGrayColor] CGColor]);
float num[] = {6.0, 6.0};
CGContextSetLineDash(context, 0.0, num, 2);
CGRect rectangle;

float x, y, width, height;

x=start.xCord;
width = end.xCord - start.xCord;

if(start.yCord < end.yCord) {
    y = start.yCord;
    height = end.yCord - start.yCord;
}
else {
    y = start.yCord;
    height = start.yCord - end.yCord;
}

rectangle = CGRectMake(x, y, width, height);
CGContextAddRect(context, rectangle);
CGContextStrokePath(context);

}

И вот как я это использую:

for (int i=1; i<sortedPointArray.count; i++) {
    ChartPoint *startPoint = [sortedPointArray objectAtIndex:i-1];
    ChartPoint *endPoint = [sortedPointArray objectAtIndex:i];
    [self drawLine:startPoint endPoint:endPoint];
 }

И ничего не отображается в моем iboChartsFieldView. Что я делаю неправильно?

Мой полный исходный код для контроля:

#import "LineChartsControl.h"
#import "ChartPoint.h"

@interface LineChartsControl ()
@property (weak, nonatomic) IBOutlet UIView *iboChartsFieldView;
@property (weak, nonatomic) IBOutlet UILabel *iboFirstTimeStampLabel;

@end

NSMutableDictionary *chartData;
NSMutableArray *pointsArray;
NSArray *sortedPointArray;
float xAxisStepInPixels;
float yAxisStepInPixels;
NSDate *xAxisMinValue;
float yAxisMinValue;
NSDate *xAxisMaxValue;
float yAxisMaxValue;

@implementation LineChartsControl

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
//[self getChartData];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

-(void)getChartData{
//Here must be code to retrieve previous data for case
chartData = [[NSMutableDictionary alloc] init];
[chartData setObject:@"4" forKey:@"2014-07-17T10:32:00+03:00"];
[chartData setObject:@"1" forKey:@"2014-07-17T10:38:00+03:00"];
[chartData setObject:@"2" forKey:@"2014-07-17T10:39:00+03:00"];
[chartData setObject:@"5" forKey:@"2014-07-17T10:40:00+03:00"];
[chartData setObject:@"3" forKey:@"2014-07-17T10:41:00+03:00"];
[chartData setObject:@"4" forKey:@"2014-07-17T10:42:00+03:00"];
[chartData setObject:@"4" forKey:@"2014-07-17T10:43:00+03:00"];
if(chartData.count>1)
{
    [self calculateXAxisLength];
    [self calculateYAxisLength];
    [self generatePointsArray];
    [self refreshChart];
    NSLog(@"%f",xAxisStepInPixels);
    NSLog(@"%f",yAxisStepInPixels);
}
}

-(void)calculateXAxisLength
{
NSDateFormatter *timeFormat = [[NSDateFormatter alloc] init];
[timeFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *xMin = [timeFormat dateFromString:@"3000-07-17T10:42:00+03:00"];
NSDate *xMax = [timeFormat dateFromString:@"1000-07-17T10:42:00+03:00"];
for (NSString *xAxis in [chartData allKeys]) {
    NSDate *date = [timeFormat dateFromString:xAxis];
    if([date timeIntervalSinceDate:xMax] > 0)
    {
        xMax = date;
    }
    if([date timeIntervalSinceDate:xMin] < 0)
    {
        xMin = date;
    }
}

NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSSecondCalendarUnit
                                                    fromDate:xMin
                                                      toDate:xMax
                                                     options:0];
xAxisMinValue = xMin;
xAxisMaxValue = xMax;
xAxisStepInPixels = self.iboChartsFieldView.frame.size.width/[components second];
}

-(void)calculateYAxisLength
{
float xMin = 99999999;
float xMax = -99999999;
for (NSString *xAxis in [chartData allKeys]) {
    float value = [chartData[xAxis] floatValue];
    if(value>xMax)
    {
        xMax = value;
    }
    if(value<xMin)
    {
        xMin = value;
    }
}
yAxisMinValue=xMin;
yAxisMaxValue=xMax;
yAxisStepInPixels = self.iboChartsFieldView.frame.size.height/(xMax-xMin);
}

-(void)generatePointsArray{
pointsArray = [[NSMutableArray alloc] init];
NSDateFormatter *timeFormat = [[NSDateFormatter alloc] init];
[timeFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
for (NSString *xAxis in [chartData allKeys]) {
    NSDate *date = [timeFormat dateFromString:xAxis];
    ChartPoint *chartPoint = [[ChartPoint alloc] init];
    NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [gregorianCalendar components:NSSecondCalendarUnit
                                                        fromDate:date
                                                          toDate:xAxisMaxValue
                                                         options:0];
    chartPoint.xCord = [components second]*xAxisStepInPixels;
    float value = [chartData[xAxis] floatValue];
    chartPoint.yCord = (value - yAxisMinValue)*yAxisStepInPixels;
    [pointsArray addObject:chartPoint];
}
NSSortDescriptor *firstDescriptor = [[NSSortDescriptor alloc] initWithKey:@"xCord" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:firstDescriptor, nil];
sortedPointArray = [[NSArray alloc]init];
sortedPointArray = [pointsArray sortedArrayUsingDescriptors:sortDescriptors];
}

- (void)drawLine:(ChartPoint*)start endPoint:(ChartPoint *) end
{
UIGraphicsBeginImageContext(self.iboChartsFieldView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetLineWidth(context, 1.0f);
CGContextSetStrokeColorWithColor(context, [[UIColor darkGrayColor] CGColor]);
float num[] = {6.0, 6.0};
CGContextSetLineDash(context, 0.0, num, 2);
CGRect rectangle;

float x, y, width, height;

x=start.xCord;
width = end.xCord - start.xCord;

if(start.yCord < end.yCord) {
    y = start.yCord;
    height = end.yCord - start.yCord;
}
else {
    y = start.yCord;
    height = start.yCord - end.yCord;
}

rectangle = CGRectMake(x, y, width, height);
CGContextAddRect(context, rectangle);
CGContextStrokePath(context);
}

-(void)refreshChart{
if(chartData.count!=sortedPointArray.count)
{
    [self calculateXAxisLength];
    [self calculateYAxisLength];
    [self generatePointsArray];
}
for (int i=1; i<sortedPointArray.count; i++) {
    ChartPoint *startPoint = [sortedPointArray objectAtIndex:i-1];
    ChartPoint *endPoint = [sortedPointArray objectAtIndex:i];
    [self drawLine:startPoint endPoint:endPoint];
}
}

@end

2 ответа

LinearInterpView - это подкласс UIView, использующий этот класс для рисования линий

#import "LinearInterpView.h"

@implementation LinearInterpView
{
    UIBezierPath *path;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder])
    {
        [self setMultipleTouchEnabled:NO];
        [self setBackgroundColor:[UIColor clearColor]];
        path = [UIBezierPath bezierPath];
        [path setLineWidth:1.];

    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    [[UIColor blackColor] setStroke];
    [path stroke];
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    [path moveToPoint:p];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    [path addLineToPoint:p];
    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesMoved:touches withEvent:event];

}


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}
@end

Если вы хотите нарисовать что-то на UIVIew, вы должны создать его подкласс и нарисовать то, что вы хотите внутри
-(void)drawRect:(CGRect)rect метод. Если этот цикл выходит из drawRect: это не сработает.

.час

#import <UIKit/UIKit.h>

@interface aView : UIView
@end

.m

#import "aView.h"

@implementation aView

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {

    }
    return self;
}

- (void)drawRect:(CGRect)rect {

    // Sample Rectangle Drawing
    UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: CGRectMake(23, 50, 24, 7)];
    [UIColor.grayColor setFill];
    [rectanglePath fill];

    // Sample Oval Drawing
    UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(24.5, 65.5, 21, 21)];
    [UIColor.blackColor setStroke];
     ovalPath.lineWidth = 1;
    [ovalPath stroke];

    // Sample Horizontal Bezier Drawing
    UIBezierPath* bezierPath = UIBezierPath.bezierPath;
    [bezierPath moveToPoint: CGPointMake(23.5, 37.5)];
    [bezierPath addCurveToPoint: CGPointMake(45.5, 37.5) controlPoint1: CGPointMake(45.52, 37.5) controlPoint2: CGPointMake(45.5, 37.5)];
    [UIColor.blackColor setStroke];
    bezierPath.lineWidth = 1;
    [bezierPath stroke];

    // Sample Vertical Bezier Drawing
    UIBezierPath* bezier2Path = UIBezierPath.bezierPath;
    [bezier2Path moveToPoint: CGPointMake(67.5, 36.5)];
    [bezier2Path addCurveToPoint: CGPointMake(67.5, 59.5) controlPoint1: CGPointMake(67.5, 59.52) controlPoint2: CGPointMake(67.5, 59.5)];
    [UIColor.blackColor setStroke];
    bezier2Path.lineWidth = 1;
    [bezier2Path stroke];

    //// Drawing Text With Attribute
    CGRect textRect = CGRectMake(0, 0, 50, 30);
    NSMutableParagraphStyle* textStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
    textStyle.alignment = NSTextAlignmentCenter;
    NSDictionary* textFontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"Helvetica" size: 12], NSForegroundColorAttributeName: UIColor.blackColor, NSParagraphStyleAttributeName: textStyle};
    [@"Hello, World!" drawInRect: textRect withAttributes: textFontAttributes];
}

@end
Другие вопросы по тегам