Как нарисовать стрелки зависимости между ячейками таблицы в iOS? - PullRequest
0 голосов
/ 04 сентября 2018

Я внедряю диаграмму Ганта в iOS. Я застрял в показе зависимости между двумя задачами.

Мне нужно показать зависимость, рисуя стрелки между зависимыми задачами.

Я использую таблицу для отображения задач.

Каждая ячейка табличного представления имеет чертежный вид, который рисует синюю линию.

Что я сделал до сих пор:

enter image description here

  • Если две ячейки A, B являются зависимыми, вычислить P1, P2, P3, P4.
  • Теперь нарисуйте линию Безье в ячейке A из P1 -> P3 -> P4.
  • Теперь нарисуйте линию Безье в ячейке B от P4 -> P2.

Это дает результат:

enter image description here

Пока это работает, но это будет усложняться по мере роста числа зависимых задач. Рисование в каждой ячейке будет влиять на отзывчивость пользовательского интерфейса, когда tableView перезагружается во время использования приложения.

Мне интересно, есть ли другой способ добиться того, что я пытаюсь сделать.

Для рисования Безье с помощью наконечника стрелки я использую следующий код, который я нашел в 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 };
}
...