2

I am trapped in a strange problem, I am making a keyboard extension, in which I need to draw highlight of key on touch. I am successfully able to do that, however strangely for some keys to the left top corner specially the keys Q and A, don't draw highlight everytime. Mainly my code looks like this..

  1. On touchbegan - Draw Highlight by calling [keysLayer setNeedsDisplay];
  2. On touchEnd - Remove Highlight by again calling [keysLayer setNeedsDisplay];

So basically, the drawRect function doesn't get called everytime on those specific keys, everything else works fine, even setNeedsDisplay gets called.

So, I am looking for help, that what can fail drawRect function to call, I want to know the list of reasons.

If anyone can help me.

Update


Adding code

In SuperView where the KeysLayer View has been added.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];

    keysLayer.drawHighlight=YES;
    keysLayer.touchLocation=[touch locationInView:self];
    [keysLayer setNeedsDisplay];
}

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

    keysLayer.drawHighlight=NO;
    [keysLayer setNeedsDisplay];
}

Inside KeysLayer UIView class

- (void)setTouchLocation:(CGPoint)location{
    self.touchLocation=location;

    bezierPathForHighlight=[self createHighLightPath];//Creating simple path based on touch location.
}

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);

    if(!self.drawHighlight)
       [bezierPathForHighlight removeAllPoints];

    [bezierPathForHighlight stroke];
    CGContextRestoreGState(context);

}

Update 2


So, I found the problem, its only occurring in my iPhone6 with iOS9.0. I verify this with this test application. Amazingly in this test application what I have found is there is a particular touch area where iOS doesn't call drawRect an iOS BUG?

See the attached image below, which explains where actually it happens. We have a problem, without a solution. Need Help.

enter image description here

Thanks.

iphonic
  • 12,615
  • 7
  • 60
  • 107
  • 2
    Post the actual code you're using, otherwise it's not likely to really know the cause. – l'L'l Oct 08 '15 at 12:06
  • did you try adding as subview instead of calling setNeedsDisplay – Teja Nandamuri Oct 08 '15 at 12:14
  • @Mr.T Yes, it is added as subview in which I got all normal keyboard keys, every key is getting highlighted perfectly on touch, just two specific keys sometimes fails to highlight aka not calling drawRect. – iphonic Oct 08 '15 at 12:21
  • 1
    can you show the code of how you call the draw method by key press ? – Teja Nandamuri Oct 08 '15 at 12:25
  • From the name `keysLayer` it sounds like you're calling a *layer's* `-setNeedsDisplay`. Is that true, and if so why mess with layers if you're working at the view level? You really haven't given much to go on, though -- **please post your code**. The problem is not in `drawRect:` the problem is in your code, and it's impossible for us to really help you debug your code if we can't see it. – Caleb Oct 08 '15 at 12:29
  • @Mr.T I have added code. – iphonic Oct 08 '15 at 12:30
  • @l'L'l I have added code, please check. – iphonic Oct 08 '15 at 12:31
  • @Caleb `keysLayer is UIView`, not CALayer it is working fine. Please read my question, I have mentioned everything working fine for all other keys, `drawRect` gets called fine, just those two keys for which it doesn't get called everytime.. – iphonic Oct 08 '15 at 12:36
  • 1
    The reason I have seen for this is when the view/layer in question is not actually visible. Add a background colour for debugging just to make sure that the keys really are where you think they are. A and Q are both near the left edge of their parent which make me wonder if they got clipped. –  Oct 08 '15 at 12:42
  • So in case if it is clipped even if setNeedsDisplay calls, drawRect won't get called? – iphonic Oct 08 '15 at 12:47
  • @iphonic: Why don't you call `keysLayer.touchLocation=[touch locationInView:self];` in `touchesEnded` also? – l'L'l Oct 08 '15 at 13:19
  • @l'L'l I can't because on touch began the highlight works and location gives me which key was touched. – iphonic Oct 08 '15 at 14:05
  • @MichaelL Hi I have added more explanation, you might be interested into it. Thanks. – iphonic Oct 09 '15 at 11:43
  • @Caleb Hi I have added more explanation, you might be interested into it. Thanks. – iphonic Oct 09 '15 at 11:44

1 Answers1

4

The problem seems to be specific to iOS 9 onwards. I can replicate it in my other devices also. The problem seems to be with UIWindow gesture recogniser. While I was checking your (@iphonic) sample code I found that if I tap and hold for a second at that specific place then the drawRect is getting called :). So it seemed to me that there is delay in touches at those places.

So I started debugging the touches for different places and found _UISystemGestureGateGestureRecognizer which is a private class is having different property in these area and what I did is I just looped through the gesture recognisers attached to the UIWindow and set the delaysTouchesBegan property to NO and thats it.

The problem is resolved. Actually the problem is not specific to that particular area instead it is with the left corner of the screen might be Apple has done some implementation for it. Though it is now working fine. I will continue my observations but for the time being its a working fix for you.

Here is a little sample code that you need to add.

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    for (UIGestureRecognizer *gesture in self.view.window.gestureRecognizers) {
        gesture.delaysTouchesBegan = NO;
    }
}

Add this code in your UIViewController after its view has appeared.

if-else-switch
  • 977
  • 1
  • 7
  • 24