I have found IR accuracy to be poor resolution (+/- a few centimeters), as it's highly dependent on the refectivity of the surface. It also frequently has very poor range (a few cm to tens of cm), depending on the emitting power of the illumination source.
I have found ultrasonics, however, even the cheap $0.99 ones you mention, to have much better resolution (+/- mm), and much better range (about 2m), depending on the code driving them. I have yet to see good non-blocking code in any library for one of these, but when I write my own non-blocking code with interrupts and basic digital signal processing, such as a median filter, I get excellent results.
So, I recommend you use ultrasonics, but it requires advanced knowledge to do it well and do it right, such as using interrupts and taking the median of every 3 to 5 samples to remove spurious results.
On very flat surfaces, such as walls, at angles 45 deg or larger, ultrasonics also do poorly, since they end up measuring the distance including the extra reflections off the walls, but contrary to what you experienced, on odd shaped or softer objects, such as humans, I find them to do much better. I have used ultrasonics as the means of detecting humans several times before with good results. The real secret/challenge is your code. And again, I have yet to find a library worth using, and good code on these cheap things makes a HUGE difference in results and reliability and accuracy!