4

I have a custom view which is not being deallocated. I dismiss controller on close button pressed. Now if I only press the button the view is deallocated alright. But If press button with one finger with other finger touching the view its not deallocated on dismiss but on the next touch event.

Its UITouch which is keeping the reference of my view and not releasing it. How can I fix this?

Here is my code for my close action:

- (IBAction)closePressed:(UIButton *)sender {
    NSLog(@"Close pressed"); 
    if (self.loader)
    [self.loader cancelJsonLoading];
    [self.plView quit];
    [self dismissViewControllerAnimated:YES completion:nil];
}
vaibhav
  • 4,038
  • 1
  • 21
  • 51
Sajad Khan
  • 512
  • 1
  • 6
  • 15

1 Answers1

1

Did you try to call:

[self.view resignFirstResponder];

That should cancel all pending UITouches.

If this doesn't work, you can keep trace of your touches:

  • define a NSMutableSet where you store current touches:

    NSMutableSet *_currentTouches;

  • in your init():

    _currentTouches = [[NSMutableSet alloc] init];

And implement:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super.touchesBegan:touches withEvent:event];
    [_currentTouches unionSet:touches]; // record new touches
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super.touchesEnded:touches withEvent:event];
    [_currentTouches minusSet:touches]; // remove ended touches
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super.touchesEnded:touches withEvent:event];
    [_currentTouches minusSet:touches]; // remove cancelled touches
}

Then, when you need to clean your touches (when you release your view for instance):

- (void)cleanCurrentTouches {
    self touchesCancelled:_currentTouches withEvent:nil];
    _currentTouchesremoveAllObjects];
}

It is, I think, a bit hacky, but the doc says:

When an object receives a touchesCancelled:withEvent: message it should clean up any state information that was established in its touchesBegan:withEvent: implementation.

Nicolas Buquet
  • 3,880
  • 28
  • 28
  • Yes I have tried that in my custom view class, It didn't work. – Sajad Khan Oct 17 '16 at 14:21
  • And did you try `self.userInteractionEnabled = NO;` ? – Nicolas Buquet Oct 17 '16 at 14:41
  • yeah, tried that too but I think that won't make sense as its already in the UIResponder chain. isn't it? – Sajad Khan Oct 17 '16 at 14:50
  • As we are talking about a UIViewController, I corrected `[self resignFirstResponder]` to `[self.view resignFirstResponder]`. The sme goes for `self.userInteractionEnabled = NO;` becoming `self.view.userInteractionEnabled = NO;`. – Nicolas Buquet Oct 17 '16 at 14:54
  • Do you really need multitouch in your view or can you configure it as : `self.view.multipleTouchEnabled = NO;`? – Nicolas Buquet Oct 17 '16 at 14:56
  • Both I tried in the view custom class which is a subview of self.view. And I need multitouch can't disable it. – Sajad Khan Oct 18 '16 at 05:46
  • and my custom view is also implementing touch events. – Sajad Khan Oct 18 '16 at 05:52
  • [self.view resignFirstResponder]; – Farrakh Javed Oct 18 '16 at 06:49
  • @NicolasBuquet Thanks for the help but I don't think its good idea to keep UITouches this way as per docs we should not retain UITouch. I found a work around for this by enabling multiple touches and exclusive touches as it allows view to handle touches it self rather than passing to other views (UIButton in my case). – Sajad Khan Oct 18 '16 at 10:43