Рисование линий в 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
Вы можете расширить это, чтобы использовать массив строк, если хотите, это простое объяснение.