如何在UIView上画线

时间:2014-07-30 11:51:50

标签: ios objective-c ipad uiview uigraphicscontext

我正在尝试创建自己的折线图控件。

我已经创建了将数据(格式:日期 - 值)转换为坐标的逻辑,现在我只需要在视图中显示这些行。

以下是我的示例数据:

enter image description here

我的控件上有一个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 个答案:

答案 0 :(得分:0)

如果你想在UIVIew上绘制一些东西,你必须将它子类化并在内部绘制你想要的东西
-(void)drawRect:(CGRect)rect方法。如果该循环超出了drawRect:,那将无效。

·H

#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

答案 1 :(得分:0)

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