1

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

目前,我正在创建一个比 iPad 尺寸稍大的 UIView,并将其放置在 UIScrollView 中。所有节点和边都被渲染,即使它们不可见。这很可能是低效的。

如何最大限度地减少绘图时间?如何创建无限可滚动/可缩放视图?

谢谢

图纸样本: 在此处输入图像描述

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);
}
4

0 回答 0