I'd like to add my thoughts since I had exactly the same problem.
I was using UITextView since it had nicer text alignment (justify, which at the time was not available in UILabel), but in order to "simulate" non-interactive-non-scrollable UILabel, I'd switch off completely scrolling, bouncing, and user interaction.
Of course, problem was that text was dynamic, and while width would be fixed, height should be recalculated every time I'd set new text value.
boundingRectWithSize didn't work well for me at all, from what I could see, UITextView was adding some margin on top which boundingRectWithSize would not get into a count, hence, height retrieved from boundingRectWithSize was smaller than it should be.
Since text was not to be updated rapidly, it's just used for some information that may update every 2-3 seconds the most, I've decided following approach:
/* This f is nested in a custom UIView-inherited class that is built using xib file */
-(void) setTextAndAutoSize:(NSString*)text inTextView:(UITextView*)tv
CGFloat msgWidth = tv.frame.size.width; // get target's width
// Make "test" UITextView to calculate correct size
UITextView *temp = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, msgWidth, 300)]; // we set some height, really doesn't matter, just put some value like this one.
// Set all font and text related parameters to be exact as the ones in targeted text view
// Ask for size that fits :P
CGSize tv_size = [temp sizeThatFits:CGSizeMake(msgWidth, 300)];
// kill this "test" UITextView, it's purpose is over
temp = nil;
// apply calculated size. if calcualted width differs, I choose to ignore it anyway and use only height because I want to have width absolutely fixed to designed value
tv.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, msgWidth, tv_size.height );
*Above code is not directly copied from my source, I had to adjust it / clear it from bunch of other stuff not needed for this article. Don't take it for copy-paste-and-it-will-work-code.
Obvious disadvantage is that it has alloc and release, for each call.
But, advantage is that you avoid depending on compatibility between how boundingRectWithSize draws text and calculates it's size and implementation of text drawing in UITextView (or UILabel which also you can use just replace UITextView with UILabel). Any "bugs" that Apple may have are this way avoided.
P.S. It would seem that you shouldn't need this "temp" UITextView and can just ask sizeThatFits directly from target, however that didn't work for me. Though logic would say it should work and alloc/release of temporary UITextView are not needed, it did not. But this solution worked flawlessly for any text I would set in.