有没有办法使用以下方法获得正确的NSString大小:
- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode
不会被2或300个字符串抛出。目前,如果我尝试在这些长字符串上使用此方法,则会错误地计算它们,并且最终会在UITextView的底部显示大量的空格。
我尝试过使用UILineBreakModeWordWrap和UILineBreakModeCharacterWrap。
调整大小正在
中完成- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat result = 44.0f;
NSString* text = nil;
CGFloat width = 0;
CGFloat tableViewWidth;
CGRect bounds = [UIScreen mainScreen].bounds;
tableViewWidth = bounds.size.width;
width = tableViewWidth - 150;
text = stringWithLongWords;
if (text) {
CGSize textSize = { width, 20000.0f };
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:10.0f] constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];
size.height += 50.0f;
result = MAX(size.height, 44.0f+30.0f);
}
return result;
}
答案 0 :(得分:21)
UITextView
与UILabel
中包含的UIScrollView
不完全相同。它的行间距与sizeWithFont:constrainedToSize:linkBreakMode:
未考虑的字体大小和边距不同。
了解字体大小后,您可以计算行数并考虑行间距。您可以猜测边距并尝试欺骗sizeWithFont:
以提供更有用的答案。
流行的解决方案似乎是:
如果您不需要任何UILabel
功能,只需使用UITextView
如果您需要hyperlinks
,则覆盖UIButtons
看起来像UILabel
上的超链接
使用屏幕外UITextView
及其sizeToFit
方法获得真实答案
我将尝试使用UILabel
并覆盖超链接按钮。我们会看到结果如何。
如果失败了,Loren Brichter(Tweetie成名)总是选择:使用UIView
将所有内容都自己绘制成CoreGraphics
。
答案 1 :(得分:9)
查看此帖子How do I size a UITextView to its content?
看起来像textView.contentSize.height应该有效(需要注意的是,只有在使用addSubview将UITextView添加到视图后才能使用正确的contentSize)
答案 2 :(得分:1)
你说你的UITableView
有不同的高度。您是否为所有单元格设置了重用标识符?可能是已经设置了高度的旧电池正在重复使用。如果这是问题,则应在重复使用时再次调整单元格的大小。
答案 3 :(得分:1)
到目前为止,我找到的最佳解决方案是使用相同的字体设置单独隐藏UITextView,并设置其文本。之后,它的contetSize应该是准确的。
答案 4 :(得分:1)
您使用的宽度是UITextView的宽度...但是您不关心该宽度,而是关注嵌套在文本视图中的实际文本区域的宽度。
默认情况下,UITextViews在其边框周围有填充,以便在键入的文本和UITextView的边缘之间产生几个像素宽的空间(顶部很长)...为了获得正确的大小,你不应该不要用
textView.frame.size.width
而是
textView.frame.size.width-(textView.contentInset.left+textView.contentInset.right+textView.textContainerInset.left+textView.textContainerInset.right+textView.textContainer.lineFragmentPadding/*left*/+textView.textContainer.lineFragmentPadding/*right*/)
^它获取UITextView的宽度并减去所有填充,因此您只剩下可键入文本区域的宽度。
同样适用于高度,除了lineFragmentPadding
没有底部,因此您只需将其减去一次而不是两次。
最终代码是这样的:
CGSize textViewContentSize = CGSizeMake(theTextView.frame.size.width-(theTextView.contentInset.left+theTextView.contentInset.right+theTextView.textContainerInset.left+theTextView.textContainerInset.right+theTextView.textContainer.lineFragmentPadding/*left*/+theTextView.textContainer.lineFragmentPadding/*right*/), theTextView.frame.size.height-(theTextView.contentInset.top+theTextView.contentInset.bottom+theTextView.textContainerInset.top+theTextView.textContainerInset.bottom+theTextView.textContainer.lineFragmentPadding/*top*//*+theTextView.textContainer.lineFragmentPadding*//*there is no bottom padding*/));
CGSize calculatedSize = [theTextView.text sizeWithFont:theTextView.font
constrainedToSize:textViewContentSize
lineBreakMode:NSLineBreakByWordWrapping];
CGSize adjustedSize = CGSizeMake(ceilf(calculatedSize.width), ceilf(calculatedSize.height));
答案 5 :(得分:0)
受@ MrNickBarker的回答启发,这是我的解决方案:
CGFloat width = 280.0f;
UITextView *t = [[UITextView alloc] init];
[t setFont:[UIFont systemFontOfSize:17]];
[label setText:@"some short or long text, works both"];
CGRect frame = CGRectMake(0, 0, width, 0);
[t setFrame:frame];
// Here's the trick: after applying the 0-frame, the content size is calculated and can be used in a second invocation
frame = CGRectMake(0, 0, width, t.contentSize.height);
[t setFrame:frame];
对我来说唯一的问题是这不适用于修改过的插图。
仍然无法相信这样的扭曲是必需的,但由于-[NSString sizeWithFont:forWidth:lineBreakMode:]
不尊重插入,填充,边距,线间距等,这似乎是目前唯一可行的解决方案(即iOS 6) )。