The intersectNode method is optimized for running fast on devices with lots of iterations per second. Due to this, it actually "estimates" collision based on math, which sometimes goes wrong at a margin of a few pixels, specially when we are speaking of square corners of PNGs.
I had this problem once too, and since i used circles I calculated distance between circles as a second verification.
So, what you can do is a custom verification INSIDE the intersectsNode if case. Assuming you handle squares, you could verify wether the x or y collides after the intersectNode. It could be something like like:
if([[self playerSpriteNode] intersectsNode: [self pSKLabelNode]]){
if(distance between x1 and x2 < size1.width/2 + size2.width/2 || distance between y1 y2 < size1.height/2 + size2.height/2){
//Your code goes here
}
}
Note that we compare central x distances with half each widths summed. This is only an example that works with squares, and most generic sprites.
I would like to point out that, while intersectsNode is slightly imprecise, this is NEEDED in order to run your game swiftly, as perfect and precise calculations per update can be very exhaustive to your device.
So, should you do a custom verification, ALWAYS call it after intersectsNode returns true, as a second verification rather than the only one.
The answer provided above by Roman pretty much does what i said, in shorter code; I just wanted to leave an explanation about why.