Search code examples
iosobjective-ccocoa-touchtouches

Neither touchesEnded nor touchesCancelled not called sometimes after touchesMoved


I Have one circular view in my application and I am moving some objects like graph in that circular view its work fine in 90% cases but at some cases its not calling TouchEnded and my reset graphs code is in TouchEnded methods so its unloaded at some point below is my code for touches delegate methods.

#pragma mark - Touch Events For Rotation of GRAPH

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch* touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];

    prevAngle = [Utilities angleBetweenPoint:touchPoint toPoint:self.view.center];
/// convert negative angle into positive angle
    if(prevAngle < 0){
        prevAngle = PI_DOUBLE + prevAngle;
    }

    //
    [_viewStaticRadialPart hideToolTip];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    CGFloat diffAngle, tempCurAngle, tempPrevAngle, curTransformAngle, newTransformAngle;

    NSLog(@"touchesMoved");
// Get the only touch (multipleTouchEnabled is NO)
    UITouch* touch = [touches anyObject];
    // Track the touch
    CGPoint touchPoint = [touch locationInView:self.view];


    curAngle = [Utilities angleBetweenPoint:touchPoint toPoint:self.view.center];

    /// convert negative angle into positive angle
    if(curAngle < 0){
        curAngle = PI_DOUBLE + curAngle;
    }
        prevAngle = curAngle;
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self resetViewsOnceRotationStops];


}
- (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    [resetViewsAfterTouchStops invalidate];
    resetViewsAfterTouchStops = nil;
}

I am stuck here since last night so any help will be appreciated.

Thanks in advance.


Solution

  • I don't know the cause for this problem from core level.

    But NSTimer can help us in

    But I feel we can resolve this by adding setting / replace NSTimer instance while touchesMoved called and we can reset that timer on touchesEnded and touchesCancelled. So, in either case, your touchesEnded or touchesCancelled not called timer will do that job and your reset logic works as it should be expected.

    Demo Source Code

    - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
    {
        NSLog(@"touchesMoved");
    
        //Timer re-initialize code here
        if (resetViewsAfterTouchStops) {
    
             [resetViewsAfterTouchStops invalidate];
             resetViewsAfterTouchStops = nil;
        }
    
        resetViewsAfterTouchStops =  [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(resetViewsOnceRotationStops) userInfo:nil repeats:NO];
    }
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        isTouched = NO;
        [resetViewsAfterTouchStops invalidate];
        resetViewsAfterTouchStops = nil;
    
        [self resetViewsOnceRotationStops];
        [self setUserInteractionOnSectorsAs:YES];
    }
    
    - (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
    {
        NSLog(@"touchesCancelled");
        if(resetViewsAfterTouchStops)
        {
             [self resetViewsOnceRotationStops];
             [self setUserInteractionOnSectorsAs:YES];
        }
    
        [resetViewsAfterTouchStops invalidate];
        resetViewsAfterTouchStops = nil;
    }
    
    - (void) resetViewsOnceRotationStops
    {
        //your reset code will be place here
    }