多点触控跟踪问题

3

我在写作时使用多点触控,所以基本上我正在做的是使用手的支撑来书写,因为通常情况下,这是用户的习惯,我按照如何忽略多点触控序列中的某些UITouch点的链接进行操作。

因此,在touchesBegan中跟踪触摸对象并仅在touchesMoved中使用它。一切正常,但有时在写作时会出现以下情况:

enter image description here

在上面的图片中,您可以看到用手触摸屏幕写字时突然出现的粗线。

以下是代码:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches began");   

    UITouch* topmostTouch = self.trackingTouch;
    for (UITouch *touch in touches)
    {
        bufIdx = 0;
        isFirstTouchPoint = YES;
        ctr = 0;

        pts[0] = [touch locationInView:self];


        if(!topmostTouch || [topmostTouch locationInView:self].y > pts[0].y)
        {
            topmostTouch = touch;
            //touchStartPoint1 = pts[0];
        }
        else
        {
            pts[0] = pts[3];
        }
    }

   if (self.trackingTouch != nil && self.trackingTouch != topmostTouch) 
   {
     [self discardDrawing];        
   }

    self.trackingTouch = topmostTouch;
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{    
        // Find the touch that we track for drawing

            CGPoint p = [self.trackingTouch locationInView:self];
            ctr++;
            pts[ctr] = p;

            if (ctr == 4)
            {
                pts[3] = midPoint(pts[2], pts[4]);

                for ( int i = 0; i < 4; i++)
                {
                    pointsBuffer[bufIdx + i] = pts[i];
                }

                bufIdx += 4;

                dispatch_async(drawingQueue, ^{
                    //UIBezierPath *offsetPath = [UIBezierPath bezierPath]; // ................. (2)

                    self.currentPath = [[DrawingPath alloc] init];                   
                    [self.currentPath setPathColor:self.lineColor];


                    if (bufIdx == 0) return;

                    LineSegment ls[4];
                    for ( int i = 0; i < bufIdx; i += 4)
                    {
                        if (isFirstTouchPoint) // ................. (3)
                        {                           
                            ls[0] = (LineSegment){pointsBuffer[0], pointsBuffer[0]};
                            [self.currentPath.path moveToPoint:ls[0].firstPoint];                      
                            isFirstTouchPoint = NO;                   
                        }
                        else
                        {
                            ls[0] = lastSegmentOfPrev;

                        }


                        float frac1 = self.lineWidth/clamp(len_sq(pointsBuffer[i], pointsBuffer[i+1]), LOWER, UPPER); // ................. (4)
                        float frac2 = self.lineWidth/clamp(len_sq(pointsBuffer[i+1], pointsBuffer[i+2]), LOWER, UPPER);
                        float frac3 = self.lineWidth/clamp(len_sq(pointsBuffer[i+2], pointsBuffer[i+3]), LOWER, UPPER);



                        ls[1] = [self lineSegmentPerpendicularTo:(LineSegment){pointsBuffer[i], pointsBuffer[i+1]} ofRelativeLength:frac1]; // ................. (5)
                        ls[2] = [self lineSegmentPerpendicularTo:(LineSegment){pointsBuffer[i+1], pointsBuffer[i+2]} ofRelativeLength:frac2];
                        ls[3] = [self lineSegmentPerpendicularTo:(LineSegment){pointsBuffer[i+2], pointsBuffer[i+3]} ofRelativeLength:frac3];



                        [self.currentPath.path  moveToPoint:ls[0].firstPoint]; // ................. (6)
                        [self.currentPath.path  addCurveToPoint:ls[3].firstPoint controlPoint1:ls[1].firstPoint controlPoint2:ls[2].firstPoint];
                        [self.currentPath.path  addLineToPoint:ls[3].secondPoint];
                        [self.currentPath.path  addCurveToPoint:ls[0].secondPoint controlPoint1:ls[2].secondPoint controlPoint2:ls[1].secondPoint];
                        [self.currentPath.path  closePath];

                        lastSegmentOfPrev = ls[3]; // ................. (7)
                    }


                     dispatch_async(dispatch_get_main_queue(), ^{
                            bufIdx = 0;

                            [m_pathArray addObject:self.currentPath];
                            [self setNeedsDisplay];

                        });
                    });


                pts[0] = pts[3];
                pts[1] = pts[4]; 
                ctr = 1;
            }
        }        
}

所以朋友们,请帮助我。

本帖中提到的方法可能适用于你Stackoverflow链接 - bhavya kothari
@bhavyakothari,我认为你没有仔细阅读我的问题,我已经按照相同的链接操作,并在我的问题中提到了它。 - Ranjit
2个回答

4
您需要进行调试以确认,但似乎与您在 touchesBegan: withEvent: 中的逻辑有关。在这个方法中,每次检查新触摸时,您会确定它是否是“最高”的,但当最高触摸确实更改时,您似乎没有中止/重置任何现有绘图。
您最好的方法可能是使用日志记录来确定“最高”触摸何时更改以及对正在进行的线条产生什么影响。
此外,在 touchesMoved: 中,您不需要使用 for (UITouch * touch in touches) 循环,因为您已经引用了 self.trackingTouch,所以可以直接使用它。

你好@Wain,感谢您的回复。根据您的建议,我已对代码进行了编辑。我的意思是我正在展示代码,以便中止任何现有的绘图。在测试过程中,我注意到一件事情,只有当您在书写时,如果您的两个或更多手指触摸屏幕下方时,它才会发生。如果除绘图手指外只有一个手指触摸,则可以正确书写。 - Ranjit
从代码来看,我猜测通过销毁 self.currentPath 并将 ctr 重置为零来重新启动您的线条绘制算法。 - Wain
1
在您添加了对 discardDrawing 的调用的地方。这只会取消当前行并开始新行。我不知道您的绘图算法或没有时间研究它,因此您需要决定如何在检测到错误触摸时取消当前行... - Wain
你好 @Wain,如果你查看我的上面的代码,我已经在touchesBegan中添加了对discardDrawing的调用。你无法查看它吗? - Ranjit
你好 @Wain,你有什么话要说吗? - Ranjit
显示剩余6条评论

1
如果我正确理解了你的问题,那么当用户在你的画布上使用多个手指时,会出现不希望出现的笔画。既然你已经有了一个 self.trackingTouch,那么忽略除 self.trackingTouch 之外的所有其他触摸是否合理呢?
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (self.trackingTouch)
    {
        // another touch is active so we ignore this one
        return;
    }
    // ...the rest of your code
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = self.trackingTouch;
    if (![touches containsObject:touch])
    {
        // updates to touches other than self.trackingTouch
        return;
    }

    // ...process only self.trackingTouch in the rest of your code
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = self.trackingTouch;
    if (![touches containsObject:touch])
    {
        // updates to touches other than self.trackingTouch
        return;
    }

    // ...process only self.trackingTouch in the rest of your code

   self.trackingTouch = nil;
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    // ...same as touchesEnded:withEvent:
}

@John,我没有进行任何重大更改,这不会改变我的原始帖子。 - Ranjit
你好@John,在touches ended中,为什么要写self.trackingTouch = nil;而在touchesBegan中,又说如果(self.trackingTouch)则返回。你能解释一下这个吗? - Ranjit
你好,@John,请查看这个链接:http://stackoverflow.com/questions/21935064/undo-with-multitouch-drawing-in-ios - Ranjit
你好,@John Estropia,我的曲线在使用手势支持时变得不平滑,你有什么建议?可能出了什么问题?这是 Stack Overflow 上的问题链接以供参考:https://dev59.com/FHzaa4cB1Zd3GeqPUs-J。 - Ranjit
你好,@John,我需要你的帮助,请帮帮我。 - Ranjit
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接