无限可滚动的UIView图表

时间:2013-07-17 20:39:05

标签: ios uiview graph uiscrollview core-graphics

我对图形比较陌生。这段代码只是在UIView中绘制图形节点和边。此代码适用于少量节点,但是当UIView中的节点数和边数超过200时,需要10秒以上才能加载,这与iPad的帧相同。我画的效率低吗?我的目标是创建一个“无限”可滚动/可缩放图形视图,其中节点和边缘仅在它们变得可见时才加载。我相信UIView的尺寸是有限的,所以在UIScrollView中插入一个非常大的UIView是行不通的。

目前,我正在创建一个略大于iPad尺寸的UIView,并将其置于UIScrollView中。即使它们不可见,也会渲染所有节点和边。这很可能效率低下。

如何最大限度地缩短抽奖时间?如何创建无限可滚动/可缩放视图?

由于

图纸示例: enter image description here

UIView代码:

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);

//Set background
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextFillRect(context, self.bounds);

//Translate the coordinate system relative to the minimum and maximum points in the graph
CGContextTranslateCTM(context, -graph.minX + MAP_BORDER_WIDTH, -graph.minY + MAP_BORDER_HEIGHT);


if (graph) {
    //Draw all edges in graph
    for (FNETEdge *edge in graph.edges) {
        [self drawEdge:edge
                inRect:rect];
    }
    //Draw all nodes in graph
    for (FNETNode *node in graph.nodes) {
        [self drawNode:node
                inRect:rect];
    }
}

CGContextRestoreGState(context);
}

- (void)drawNode:(FNETNode*)node inRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);

//Get the size of the text
NSMutableAttributedString *text = node.getAttributedText;
CGSize maxTextSize = [text boundingRectWithSize:CGSizeMake(0, 0) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;

//Find the width and height of the node
CGFloat width = NODE_PADDING + node.icon.size.width + NODE_SPACING + maxTextSize.width + NODE_PADDING;
CGFloat height = node.icon.size.height > maxTextSize.height ? (NODE_PADDING + node.icon.size.height + NODE_PADDING) : (NODE_PADDING + maxTextSize.height + NODE_PADDING);

//Top left corner of the node
CGPoint topLeftPoint = CGPointMake(node.center.x - width/2, node.center.y - height/2);

//Inner and outer rectangles for node
CGRect outerNodeRect = CGRectMake(topLeftPoint.x, topLeftPoint.y, width, height);
CGRect innerNodeRect = CGRectMake(topLeftPoint.x + NODE_PADDING, topLeftPoint.y + NODE_PADDING, width - (2 * NODE_PADDING), height - (2 * NODE_PADDING));

//Find where we will draw the icon and the text
CGRect iconRect = CGRectMake(innerNodeRect.origin.x, topLeftPoint.y + (height - node.icon.size.height) / 2, node.icon.size.width, node.icon.size.height);
CGRect textRect = CGRectMake(innerNodeRect.origin.x + node.icon.size.width + NODE_SPACING, innerNodeRect.origin.y, maxTextSize.width, maxTextSize.height);

//Fill background
[[node getDeviceColor] setFill];
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:outerNodeRect cornerRadius:8];
[roundedRect fillWithBlendMode: kCGBlendModeNormal alpha:1.0f];

//Draw icon
[node.icon drawInRect:iconRect];

//Draw text
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
[text drawWithRect:textRect options:NSStringDrawingUsesLineFragmentOrigin context:nil];

CGContextRestoreGState(context);
}

- (void)drawEdge:(FNETEdge*)edge inRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);

CGContextSetLineCap(context, kCGLineCapSquare);
CGContextSetStrokeColorWithColor(context, [edge getSpeedColor].CGColor);
CGContextSetLineWidth(context, EDGE_LINE_WIDTH);

//Iterate through all points and connect the dots!
for (int i = 0; i < edge.points.count -1; i++) {
    CGPoint startPoint = ((NSValue*)[edge.points objectAtIndex:i]).CGPointValue;
    CGPoint endPoint = ((NSValue*)[edge.points objectAtIndex:i+1]).CGPointValue;

    CGContextMoveToPoint(context, startPoint.x, startPoint.y);
    CGContextAddLineToPoint(context, endPoint.x, endPoint.y);
}

CGContextStrokePath(context);
CGContextRestoreGState(context);
}

0 个答案:

没有答案