1

我想有一个类用于在其中呈现简单的图表(没有复杂的东西)。我的想法是/是:

  • Sublass an UIView--> 让我们称之为Grapher
  • 在其中实现我的所有方法 ( drawBarGraph, drawProgressBar, drawLineGraph)
  • 将其包含在所需的视图控制器中,创建 的实例Grapher,调用所需的方法
  • 将该实例作为子视图添加到我的主视图中。

让我们跳入一些代码,因为我不知道如何解释这一点。这是grapher.h

@interface Grapher : UIView
{
    CGContextRef context; //for passing it in via constructor

    //UIColor *backgroundColor;
    UIColor *graphColor; //foreground color
}

- (id)initWithFrame:(CGRect)frm inContext:(CGContextRef)ctx;

- (void)setGraphColor:(UIColor*)color;

- (void)drawHistogramWithItems:(NSArray*)items;
//- (void)drawLineChartWithItems:(NSArray*)items;
- (void)drawProgressLineWithPercentage:(float)percent;

以及相应的grapher.m

@implementation Grapher

- (id)initWithFrame:(CGRect)frm inContext:(CGContextRef)ctx
{
    self = [super initWithFrame:frm];
    if (self)
    {
        context = ctx;
    }
    return self;
}

#pragma Mark main draw methods

- (void)drawHistogramWithItems:(NSArray *)items
{
    //[backgroundColor set];
    //UIRectFill(frame);
    [graphColor set];

    int itemWidth = 20;

    if (items.count == 0) return;

    float max = -1;
    for (SFGraphItem *item in items)
        if (item.value > max)
            max = item.value;

    float spacing = (frame.size.width - (itemWidth * items.count)) / (items.count + 1);
    float xPos = spacing;

    for (int i = 0; i < items.count; i++)
    {
        CGFloat itemHeight = ((SFGraphItem*)[items objectAtIndex:i]).value / max * frame.size.height;
        CGRect bar = CGRectMake(xPos, frame.origin.y + frame.size.height - itemHeight, itemWidth, itemHeight);
        CGContextAddRect(context, bar);
        CGContextDrawPath(context, kCGPathFill);
        xPos += spacing + itemWidth;
    }

}

- (void)drawProgressLineWithPercentage:(float)percent
{
    //[backgroundColor set];
    //UIRectFill(frame);
    [graphColor set];
    UIRectFill(CGRectMake(frame.origin.x, frame.origin.y, frame.size.width / 100 * percent, frame.size.height));
}

#pragma Mark setters/getters

- (void)setGraphColor:(UIColor *)color
{
    graphColor = color;
}

@end

很好很简单。如果我将它子类化为另一个文件中的NSObjectthen 子类UIView(让我们调用它),在那里GraphArea覆盖,然后传递它就可以了。drawRectalloc-initGrapherUIGraphicsGetCurrentContext()

但我不想要一个“中间观点”。我想子类化UIViewGrapher这样做:

Grapher *graph = [[Grapher alloc] initWithFrame:CGRectMake(5, 65, winSize.width - 10, 20)]; //some random frame
[graph setGraphColor:[UIColor redColor]];
[graph drawProgressLineWithPercentage:50];
graph.backgroundColor = [UIColor grayColor];

[someview addSubview:graph];

如果我用CGContextRefor 这个调用构造函数并尝试在那里获取上下文,它总是为空的。如何在当前上下文中传递?我做错了什么以及如何解决这个问题?
如果我解释得太草率,请告诉我,我会更加努力。

干杯,简。

4

1 回答 1

2

我做错了什么以及如何解决这个问题?

如果我理解正确,那么您会误解视图的作用。

视图在自己的空间中管理自己的绘图。你不给它一个上下文,你让它根据需要创建或设置一个上下文并在它自己的坐标系中绘制。听起来您正在尝试创建一个在另一个视图的上下文中绘制的视图,而我想不出一个这样做的好理由。从 UIView 的文档中,就在页面顶部:

UIView 类定义了屏幕上的一个矩形区域以及用于管理该区域内容的接口。在运行时,视图对象处理其区域内任何内容的呈现,并处理与该内容的任何交互。

如果您尝试创建一个仅在另一个视图中绘制某些内容的视图,那么您做错了。将您的绘图方法封装在某个类中并使用该类的实例在视图中绘制图形可能很好,但如果这是您想要的,您不应该将该类作为 UIView 的子类。

如果我将其子类化为 NSObject,然后在另一个文件中子类化 UIView(我们称之为 GraphArea),在那里覆盖 drawRect,分配初始化 Grapher 并在其中传递 UIGraphicsGetCurrentContext() 就可以了。

子类化 UIView 很好,但是 UIView 子类尝试在其他视图的空间中绘制是不行的。如果您想创建一个可以作为内容添加到其他视图的图形,但不能使该图形成为它自己的视图,那么您可以查看 CALayer。使用图层,您可以覆盖-drawInContext:以进行绘图。您可以创建图层并将其添加到现有视图。绘图系统会将您的图层与视图的其他图层合成。

于 2013-08-06T15:10:03.727 回答