Рисование линий в iOS

Как нарисовать прямую линию в iOS независимо от того, как пользователь ее рисует.

Я хочу, чтобы длина строки соответствовала количеству пикселей, которые пользователь перетаскивает.

Но он должен быть вертикальным или горизонтальным в зависимости от того, скользит ли пользователь пальцем слева направо от экрана или сверху вниз.

Линии не должны быть косыми или любой другой формы. Это должно быть прямо.

Я просмотрел статьи, в которых говорится, что "Open GL" - единственный путь.

Я сам пытался его кодировать, но когда я меняю направление с вертикального на горизонтальное или наоборот, я получаю дополнительную линию или разрыв между тем, где заканчивается горизонтальная линия и где начинается вертикальная линия:

В заголовочном файле:

@interface ViewController : UIViewController
{
    BOOL mouseSwiped;
    CGPoint lastPoint;
    CGPoint previousPoint;
    UIBezierPath *currentPath;
    CGFloat lastPointY;
    CGFloat lastPointX;
    BOOL xchanging;
    BOOL ychanging;
    NSMutableArray *arrayTouch;
}
@property (weak, nonatomic) IBOutlet UIImageView *drawImage;
@property UIBezierPath *currentPath;
@end

В файле реализации:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {


    mouseSwiped = NO;
    UITouch *touch = [touches anyObject];

    if ([touch tapCount] == 2) {
        drawImage.image = nil;
        [arrayTouch removeAllObjects];
        return;
    }

    lastPoint = [touch locationInView:self.view];
    [arrayTouch addObject:touch];
    lastPointY  = lastPoint.y;
    lastPointX = lastPoint.x;
    lastPoint.y -= 1;
} 


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    mouseSwiped = YES;

    UITouch *touch = [touches anyObject];
    CGPoint currentPoint = [touch locationInView:self.view];
    currentPoint.y -= 1;
    int currentPointXVal = currentPoint.x;
    int currentPointYVal = currentPoint.y;

    int lastPointXVal = lastPoint.x;
    int lastPointYVal = lastPoint.y;

    int diffX = abs(currentPointXVal - lastPointXVal);
    int diffY = abs(currentPointYVal - lastPointYVal);

    if(currentPoint.x > lastPoint.x && diffX > diffY)
    {
        if(ychanging == YES)
        {
            lastPointY  = currentPoint.y;
            lastPointX = currentPoint.x;
            ychanging = NO;
        }
        xchanging = YES;
        NSLog(@"x increasing");
        NSLog(@"currentPoint: %@",NSStringFromCGPoint(currentPoint));
        NSLog(@"lastPoint: %@",NSStringFromCGPoint(lastPoint));

        UIGraphicsBeginImageContext(self.view.frame.size);
        [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
        CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
        CGContextBeginPath(UIGraphicsGetCurrentContext());
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPointY);
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, lastPointY);
        CGContextStrokePath(UIGraphicsGetCurrentContext());
        drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }

    if(currentPoint.y > lastPoint.y && diffY > diffX)
    {
        if(xchanging == YES)
        {
            lastPointY  = currentPoint.y;
            lastPointX = currentPoint.x;
            xchanging = NO;
        }
        ychanging = YES;
        NSLog(@"y increasing");
        NSLog(@"currentPoint: %@",NSStringFromCGPoint(currentPoint));
        NSLog(@"lastPoint: %@",NSStringFromCGPoint(lastPoint));

        UIGraphicsBeginImageContext(self.view.frame.size);
        [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
        CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
        CGContextBeginPath(UIGraphicsGetCurrentContext());
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPointX, lastPoint.y);
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPointX, currentPoint.y);
        CGContextStrokePath(UIGraphicsGetCurrentContext());
        drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }

    if(currentPoint.x < lastPoint.x && diffX > diffY)
    {
        if(ychanging == YES)
        {
            lastPointY  = currentPoint.y;
            lastPointX = currentPoint.x;
            ychanging = NO;
        }
        xchanging = YES;
        NSLog(@"x decreasing");
        NSLog(@"currentPoint: %@",NSStringFromCGPoint(currentPoint));
        NSLog(@"lastPoint: %@",NSStringFromCGPoint(lastPoint));

        UIGraphicsBeginImageContext(self.view.frame.size);
        [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
        CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
        CGContextBeginPath(UIGraphicsGetCurrentContext());
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPointY);
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, lastPointY);
        CGContextStrokePath(UIGraphicsGetCurrentContext());
        drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }

    if(currentPoint.y < lastPoint.y && diffY > diffX)
    {
        if(xchanging == YES)
        {
            lastPointY  = currentPoint.y;
            lastPointX = currentPoint.x;
            xchanging = NO;
        }

        ychanging = YES;
        NSLog(@"y decreasing");
        NSLog(@"currentPoint: %@",NSStringFromCGPoint(currentPoint));
        NSLog(@"lastPoint: %@",NSStringFromCGPoint(lastPoint));

        UIGraphicsBeginImageContext(self.view.frame.size);
        [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
        CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
        CGContextBeginPath(UIGraphicsGetCurrentContext());
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPointX, lastPoint.y);
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPointX, currentPoint.y);
        CGContextStrokePath(UIGraphicsGetCurrentContext());
        drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

    }





    lastPoint = currentPoint;

}

Есть ли способ сделать это без Open GL?

1 ответ

Решение

Конечно - Вы можете сделать это, просто уберите наклон от линии:

@implementation LineDrawingView
{
    CGPoint touchStart;
    CGPoint touchCurrent;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        touchStart   = (CGPoint) { -1, -1 };
        touchCurrent = (CGPoint) { -1, -1 };
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    if (touchStart.x != -1)
    {
        // calculate the line rotation
        enum { horizontal, vertical } lineRot = horizontal;

        if (touchStart.y == touchCurrent.y)
        {
            // straight line
            lineRot = horizontal;
        }
        else
        {
            // calculate the slope
            double slope = fabs((touchCurrent.y - touchStart.y) / (touchCurrent.x - touchStart.x));

            if (slope > 1)
                lineRot = vertical;
        }

        // draw the actual line
        CGPoint lineEndPoint = { };

        if (lineRot == horizontal)
            lineEndPoint = (CGPoint) { touchCurrent.x, touchStart.y }; // horizontal line
        else
            lineEndPoint = (CGPoint) { touchStart.x, touchCurrent.y }; // vertical line

        // actually draw the line
        [[UIColor redColor] setStroke];

        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:touchStart];
        [path addLineToPoint:lineEndPoint];

        [path stroke];
    }
}

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchStart = [[touches anyObject] locationInView:self];
    touchCurrent = touchStart;
    [self setNeedsDisplay];
}

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchCurrent = [[touches anyObject] locationInView:self];
    [self setNeedsDisplay];
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchStart = touchCurrent = (CGPoint) { -1, -1 };
    [self setNeedsDisplay];
}

@end

Вы можете расширить это, чтобы использовать массив строк, если хотите, это простое объяснение.

Другие вопросы по тегам