A while ago, I looked at the 24-hour line chart of ink weather, and I felt very interesting. In particular, the View inside moves in real time with finger sliding, and the effect is very good. I tried to write it, and let’s have a look at the final effect:









It’s not that hard to write this line diagram and make it slippable. Draw directly on the UIScrollView, mainly the motion of the rounded View trajectory calculation. To compute the trajectory, you just compute the x and y coordinates. So here’s how I think about it

1. Motion coordinates are divided into X and Y coordinates. So let’s figure out the coordinates of x. It is easy to derive the following formula from proportional relations

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGSize size = scrollView.contentSize;
    CGFloat x = (_dataArray.count - 1) * self.lineSpace * scrollView.contentOffset.x / (size.width - scrollView.width) + self.leftMargin;
}Copy the code

DataArray is the data source array, lineSpace is the distance between each point, and leftMargin is the margin of the curve. 2. The curve itself consists of an infinite number of straight lines. We can do this by looking at the coordinates of points on a curve. After the x point coordinates of the real-time motion track are worked out, let’s calculate the Y coordinate:

  • Compute the subscripts of the positions in the array of positions of the two points before and after this point on the Bezier curve
  • So when you get two points, it’s pretty easy. Solution of linear equation
  • Find the slope, in point-slope form. Point-slope formula: y-y1 = k(x-x1)
-(CGFloat)getLableyAxisWithX:(CGFloat)xAxis;
{
    CGPoint startPoint,endPoint;
    NSInteger index;
    CGFloat sum = self.leftMargin;
    for (index = 0; index < _dataArray.count; index{+ +)sum += self.lineSpace;
        if (xAxis < sum)
        {
            startPoint = CGPointMake(_modelPostionArray[index].xPosition, _modelPostionArray[index].yPosition);
            _currentIndex = index;
            break;
        }
    }
    endPoint = CGPointMake(_modelPostionArray[index+1].xPosition, _modelPostionArray[index+1].yPosition);
    CGFloat k = (endPoint.y - startPoint.y) / (endPoint.x -startPoint.x);
    CGFloat y = k *(xAxis - startPoint.x) + startPoint.y;
    return y;
}Copy the code

3. The View of the rounded arrow is also drawn by Bezier curve. The rounded Angle can be calculated by calculating the corresponding angles of the four rounded corners.





- (void)addCirLayer
{
    self.lineLayer = [CAShapeLayer layer];
    self.lineLayer.strokeColor = [UIColor clearColor].CGColor;
    self.lineLayer.fillColor = [[UIColor whiteColor] CGColor];
    self.lineLayer.lineWidth = 1;
    self.lineLayer.contentsScale = [UIScreen mainScreen].scale;
    [self.layer addSublayer:self.lineLayer];

    CGSize size = self.size;
    UIBezierPath *path = [UIBezierPath bezierPath];
    double offsetH = size.height - RADIUS*2 - AllowSize.height;
    double offsetW = (size.width - RADIUS*2) /2;
    CGPoint point = CGPointMake(RADIUS, 0);
    [path moveToPoint:point];
    point.x += size.width - RADIUS*2;
    point.y += RADIUS;
    [path addArcWithCenter:point radius:RADIUS startAngle:M_PI*3/2 endAngle:0 clockwise:YES];
    point.x += RADIUS;
    point.y += offsetH;
    [path addLineToPoint:point];
    point.x -= RADIUS;
    [path addArcWithCenter:point radius:RADIUS startAngle:0 endAngle:M_PI/2 clockwise:YES];
    point.y += RADIUS;
    point.x -= offsetW;
    [path addLineToPoint:point];
    point.x -= AllowSize.width/2;
    point.y += AllowSize.height;
    [path addLineToPoint:point];
    point.x -= AllowSize.width/2;
    point.y -= AllowSize.height;
    [path addLineToPoint:point];
    point.x-= offsetW;
    [path addLineToPoint:point];
    point.y -= RADIUS;
    [path addArcWithCenter:point radius:RADIUS startAngle:M_PI/2 endAngle:M_PI clockwise:YES];
    point.x -= RADIUS;
    point.y -= offsetH;
    [path addLineToPoint:point];
    point.x += RADIUS;
    [path addArcWithCenter:point radius:RADIUS startAngle:M_PI endAngle:M_PI*3/2 clockwise:YES];
    [path closePath];
    self.lineLayer.path = path.CGPath;
}Copy the code

4. On the drawing of smooth Bezier curve 1. 2. It can also be drawn by calculating two control points. The drawing method here draws lessons from the method of a big bull on the net, and its choice is the second method.

-(void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2Copy the code

Wrote last

2. If you think it’s not bad, give it a little star. If you have a better idea, please leave a message to me