【问题标题】:Draw straight line with two fingers用两根手指画直线
【发布时间】:2013-04-22 03:53:25
【问题描述】:

如何在用户仍在进行拖动或触摸时用 2 根手指绘制/绘制一条直线,并且这条线是可见的?我已经尝试过使用 coregraphics 进行简单的绘画,但这对我来说似乎有点复杂。

【问题讨论】:

  • 在 touchesBegan 和 touchesMoved 中跟踪触摸。使用 CoreGraphics 在视图 DrawRect 中绘制它们。
  • 我现在可以在我的视图中跟踪触摸,问题是用两根手指如何检测另一根手指的当前位置(x 和 y)?因为我需要同时获取第一根和第二根手指的 x 和 y 来确定画线的位置。
  • @jeraldov:每次触摸对应一根手指。

标签: ios xcode core-graphics


【解决方案1】:

就贾斯汀而言,只需处理 touchesBegantouchesMoved

因此,如果您将UIView 子类化,CoreGraphics 实现可能如下所示:

@interface CustomView ()

@property (nonatomic, strong) NSMutableArray *paths;
@property (nonatomic, strong) UIBezierPath *currentPath;

@end

@implementation CustomView

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setMultipleTouchEnabled:YES];
    }
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.currentPath)
    {
        if (!self.paths)
            self.paths = [NSMutableArray array];

        self.currentPath = [UIBezierPath bezierPath];
        self.currentPath.lineWidth = 3.0;

        [self.paths addObject:self.currentPath];

        [self touchesMoved:touches withEvent:event];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ([touches count] != 2)
        return;

    [self.currentPath removeAllPoints];

    __block NSInteger i = 0;
    [touches enumerateObjectsUsingBlock:^(UITouch *touch, BOOL *stop) {
        CGPoint location = [touch locationInView:self];

        if (i++ == 0)
            [self.currentPath moveToPoint:location];
        else
            [self.currentPath addLineToPoint:location];
    }];

    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.currentPath = nil;
}

- (void)drawRect:(CGRect)rect
{
    [[UIColor redColor] setStroke];
    [[UIColor clearColor] setFill];

    for (UIBezierPath *path in self.paths)
    {
        [path stroke];
    }
}

- (void)reset
{
    self.paths = nil;
    [self setNeedsDisplay];
}

@end

或者,您也可以使用 Quartz 2D 并定义自己的 CAShapeLayer 对象,然后您的视图子类或视图控制器可以执行类似的操作(不用说,这是视图控制器实现;视图实现应该很明显):

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@property (nonatomic, weak) CAShapeLayer *currentLayer;
@property (nonatomic, strong) UIBezierPath *currentPath;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.view setMultipleTouchEnabled:YES];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.currentLayer)
    {
        CAShapeLayer *layer = [CAShapeLayer layer];
        layer.lineWidth = 3.0;
        layer.strokeColor = [[UIColor redColor] CGColor];
        layer.fillColor = [[UIColor clearColor] CGColor];
        [self.view.layer addSublayer:layer];
        self.currentLayer = layer;

        self.currentPath = [UIBezierPath bezierPath];

        [self touchesMoved:touches withEvent:event];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ([touches count] != 2)
        return;

    [self.currentPath removeAllPoints];

    __block NSInteger i = 0;
    [touches enumerateObjectsUsingBlock:^(UITouch *touch, BOOL *stop) {
        CGPoint location = [touch locationInView:self.view];

        if (i++ == 0)
            [self.currentPath moveToPoint:location];
        else
            [self.currentPath addLineToPoint:location];
    }];

    self.currentLayer.path = [self.currentPath CGPath];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.currentPath = nil;
    self.currentLayer = nil;
}

- (IBAction)didTouchUpInsideClearButton:(id)sender
{
    for (NSInteger i = [self.view.layer.sublayers count] - 1; i >= 0; i--)
    {
        if ([self.view.layer.sublayers[i] isKindOfClass:[CAShapeLayer class]])
            [self.view.layer.sublayers[i] removeFromSuperlayer];
    }
}

@end

对于后一种方法,您需要add the QuartzCore.framework to your project

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    相关资源
    最近更新 更多