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