我对图形比较陌生。这段代码只是在 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);
}