如何在iOS中的表格单元格之间绘制依赖关系箭头?

时间:2018-09-04 16:55:09

标签: ios uitableview uibezierpath gantt-chart

我正在iOS中实现Gant Chart。我坚持展示两个任务之间的依赖关系。

我需要通过在相关任务之间绘制箭头来显示相关性。

我正在使用tableview来显示任务。

每个表格视图单元格都有一个绘制蓝线的绘制视图。

到目前为止我所做的:

enter image description here

  • 如果两个单元格A,B是从属单元,则计算P1,P2,P3,P4。
  • 现在从P1-> P3-> P4在单元格A中绘制一条贝塞尔曲线。
  • 现在从P4-> P2在单元格B中绘制一条贝塞尔曲线。

结果如下:

enter image description here

目前可以使用,但是随着相关任务数量的增加,它将变得更加复杂。在应用程序使用过程中重新加载tableView时,在每个单元格上绘制会影响UI响应能力。

我想知道还有其他方法可以实现我想要做的事情。

要绘制带有箭头的贝塞尔曲线,我使用在SO中找到的以下代码。

+(UIBezierPath *)dqd_bezierPathWithArrowFromPoint:(CGPoint)startPoint
toPoint:(CGPoint)endPoint
tailWidth:(CGFloat)tailWidth
headWidth:(CGFloat)headWidth
headLength:(CGFloat)headLength {
    CGFloat length = hypotf(endPoint.x - startPoint.x, endPoint.y - startPoint.y);

    CGPoint points[kArrowPointCount];
    [self dqd_getAxisAlignedArrowPoints:points
                              forLength:length
                              tailWidth:tailWidth
                              headWidth:headWidth
                             headLength:headLength];

    CGAffineTransform transform = [self dqd_transformForStartPoint:startPoint
                                                          endPoint:endPoint
                                                            length:length];

    CGMutablePathRef cgPath = CGPathCreateMutable();
    CGPathAddLines(cgPath, &transform, points, sizeof points / sizeof *points);
    CGPathCloseSubpath(cgPath);

    UIBezierPath *uiPath = [UIBezierPath bezierPathWithCGPath:cgPath];
    CGPathRelease(cgPath);
    return uiPath;
}

+ (void)dqd_getAxisAlignedArrowPoints:(CGPoint[kArrowPointCount])points
                            forLength:(CGFloat)length
                            tailWidth:(CGFloat)tailWidth
                            headWidth:(CGFloat)headWidth
                           headLength:(CGFloat)headLength {
    CGFloat tailLength = length - headLength;
    points[0] = CGPointMake(0, tailWidth / 2);
    points[1] = CGPointMake(tailLength, tailWidth / 2);
    points[2] = CGPointMake(tailLength, headWidth / 2);
    points[3] = CGPointMake(length, 0);
    points[4] = CGPointMake(tailLength, -headWidth / 2);
    points[5] = CGPointMake(tailLength, -tailWidth / 2);
    points[6] = CGPointMake(0, -tailWidth / 2);
}

+ (CGAffineTransform)dqd_transformForStartPoint:(CGPoint)startPoint
                                       endPoint:(CGPoint)endPoint
                                         length:(CGFloat)length {
    CGFloat cosine = (endPoint.x - startPoint.x) / length;
    CGFloat sine = (endPoint.y - startPoint.y) / length;
    return (CGAffineTransform){ cosine, sine, -sine, cosine, startPoint.x, startPoint.y };
}

0 个答案:

没有答案