我想补充一下自己的想法,因为我遇到了完全相同的问题。
我之所以使用UITextView
它,是因为它具有更好的文本对齐方式(对齐,当时尚不可用UILabel
),但是为了“模拟”非交互式非滚动式UILabel
,我将完全关闭滚动,弹跳和用户交互。
当然,问题在于文本是动态的,尽管宽度是固定的,但是每次我设置新的文本值时都应重新计算高度。
boundingRectWithSize
从我所看到的,这对我来说根本不适合我, UITextView
在顶部增加了一些边距,这boundingRectWithSize
不会被计算在内,因此,从中检索到的高度boundingRectWithSize
比应该的要小。
由于文本不会快速更新,因此仅用于某些信息,这些信息最多每2-3秒更新一次,因此我决定采用以下方法:
/* 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
[temp setFont:tv.font];
[temp setTextAlignment:tv.textAlignment];
[temp setTextColor:tv.textColor];
[temp setText:text];
// Ask for size that fits :P
CGSize tv_size = [temp sizeThatFits:CGSizeMake(msgWidth, 300)];
// kill this "test" UITextView, it's purpose is over
[temp release];
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 );
}
*以上代码不是直接从我的源代码中复制的,我必须对其进行调整/从本文不需要的其他内容中清除它。不要将其用于复制粘贴并可以工作的代码。
明显的缺点是,每个调用都有分配和释放。
但是,这样做的好处是,您避免依赖boundingRectWithSize绘制文本和计算文本的大小以及文本绘制的实现之间的兼容性UITextView
(或者UILabel
也可以只替换UITextView
为UILabel
)。这样可以避免Apple可能遇到的任何“错误”。
PS似乎您不需要这个“临时”人员UITextView
,可以sizeThatFits
直接向目标询问,但这对我没有用。尽管逻辑上会说它应该工作,并且UITextView
不需要分配/释放临时文件,但事实并非如此。但是对于我要输入的任何文本,此解决方案都可以完美地工作。
lineBreakMode
?