Я внедряю диаграмму Ганта в iOS. Я застрял в показе зависимости между двумя задачами.
Мне нужно показать зависимость, рисуя стрелки между зависимыми задачами.
Я использую таблицу для отображения задач.
Каждая ячейка табличного представления имеет чертежный вид, который рисует синюю линию.
Что я сделал до сих пор:
- Если две ячейки A, B являются зависимыми, вычислить P1, P2, P3, P4.
- Теперь нарисуйте линию Безье в ячейке A из P1 -> P3 -> P4.
- Теперь нарисуйте линию Безье в ячейке B от P4 -> P2.
Это дает результат:
Пока это работает, но это будет усложняться по мере роста числа зависимых задач. Рисование в каждой ячейке будет влиять на отзывчивость пользовательского интерфейса, когда 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 };
}