- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在项目中的要求是UITextView
的字体大小应该根据UITextView
的内容减小。所以我正在尝试使用 boundingRectWithSize
来估计文本的大小。
问题是我得到的字体大小有点太大,并且文本的某些部分确实被剪掉了。
我的功能:
-(BOOL)updateTextViewFontSizeForText:(NSString*)text{
float fontSize = self.maximumFontSizeInPoints;
self.font = [self.font fontWithSize:fontSize];
CGSize tallerSize ;
CGSize stringSize ;
do
{
if (fontSize <= self.minimumFontSizeInPoints) // it just won't fit
return NO;
fontSize -= 1.0;
self.font = [self.font fontWithSize:fontSize];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
NSDictionary *attributes = @{ NSFontAttributeName: self.font, NSParagraphStyleAttributeName : paragraphStyle };
tallerSize = CGSizeMake(self.frame.size.width,self.frame.size.height-16);// the 16 is given because uitextview adds some offset
stringSize = [text boundingRectWithSize:CGSizeMake(self.contentSize.width,CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
}while(stringSize.height >= tallerSize.height);
if ([self.onTextChangDelegate respondsToSelector:@selector(onTextChangDelegate)]) {
[self.onTextChangDelegate onTextChanged:text];
}
return YES;
}
最佳答案
我在尝试做同样的事情时遇到了同样的问题。
问题在于 UITextView
与 boundingRectWithSize 相比如何运行其换行符。您可以在此处阅读更多详细信息:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/Concepts/CalcTextLayout.html
但是您实际上可以计算出确切的大小! UITextView
基本上有两个属性,您需要考虑这些属性才能获得正确的大小估计值。第一个是 textContainer.lineFragmentPadding
,第二个是 textContainerInset
。
首先,textContainer.lineFragmentPadding
:您可能已经注意到您的大小通常总是偏离10px
,这是因为系统默认值为5px
。在计算估计尺寸时,您需要从要检查的尺寸中减去该值,并在获得最终值时将其加回去。
其次,textContainerInset
。这是一个 UIEdgeInset
,您需要将其添加回最终计算值以匹配系统。
这是基于我如何解决问题的代码:
- (CGSize)sizeThatFits:(CGSize)size
CGFloat lineFragmentPaddings = self.textContainer.lineFragmentPadding * 2;
CGFloat horzPadding = self.textContainerInset.left + self.textContainerInset.right + lineFragmentPaddings;
CGFloat vertPadding = self.textContainerInset.top + self.textContainerInset.bottom;
size.width -= horzPadding;
CGRect boundingRect = [attributedText boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin context:nil];
size = boundingRect.size;
// I found through debugging that adding 0.25 rounded
// matches sizeThatFits: identically. Not sure why…
size.width += horzPadding + 0.25;
size.height += vertPadding + 0.25;
size = CGSizeRound(size);
return size;
}
请注意,CGSizeRound
只是我编写的一个自定义函数,它对 CGSize
的width
和 height
进行舍入到最近的 0.5
。
为了比较,如果您创建第二个 UITextView
,并确保 textContainer.lineFragmentPadding
和 textContainerInset
相同,您应该会看到这些值几乎与最接近的 0.5
相同。
关于计算适当的 pointSize 的问题,这是一些伪代码:
CGFloat pointSize = 64;
CGFloat minPointSize = 32;
CGFloat decrementor = 4;
CGFloat padding = self.textContainerInset.left + self.textContainerInset.right + lineFragmentPaddings;
CGFloat actualWidth = self.maxTextViewSize.width - padding * 2;
CGRect boundingRect = CGRectZero;
BOOL isValidPointSize = NO;
do {
if (pointSize < minPointSize) {
pointSize = minPointSize;
boundingRect.size.height = self.maxTextViewSize.height;
isValidPointSize = YES;
} else {
NSDictionary *defaultAttributes = [self.customTextStorage defaultAttributesForPointSize:pointSize];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:string attributes:defaultAttributes];
boundingRect = [attrString boundingRectWithSize:CGSizeMake(actualWidth, 1024) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
// is the height to big?
if (boundingRect.size.height > self.maxTextViewSize.height) {
// reduce the point size for next iteration of loop
pointSize -= decrementor;
}
// passes height test
else {
isValidPointSize = YES;
}
}
} while (!isValidPointSize);
return pointSize;
同样,以上是基于我的实现的伪代码(并不意味着只是替换现有的代码)。希望这对您有所帮助!
关于ios - boundingRectWithSize 不复制 UITextView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22834193/
有谁知道解决方法或我目前在这里做错了什么。 CGSize boundingSize = CGSizeMake(288, 9999); CGRect boundingRect = [text bound
我正在尝试创建一个 UITableViewCell包含 UITextView当用户在 textview 中输入文本时,单元格应该相应地增长。 到目前为止,这也很有效,除了 boundingRectWi
当我使用boundingRectWithSize计算文本的高度时,它崩溃了。我发现可能是因为文本中有一些表情符号。有人可以告诉我如何解决这个问题。 CGFloat kScreenMargin
我在使用 Swift 语言的 boundingRectWithSize 和多行 UILabel 方面遇到了一个奇怪的问题。我目前正在 Xcode Playground 中工作,因此我可以实时查看 UI
我正在使用 BoundingRectWithSize 取回一个 CGRect,它将适本地修复我的文本。我以前有这个代码。 var maximumLabelSize: CGSize = CGSize(w
我创建一个 UITextView,向其中添加文本,然后将其放入 View (带有容器) UITextView *lyricView = [[UITextView alloc] initWithFram
我有一个长度会改变的字符串。我有一个固定宽度和高度的 textView。我想找到适合这些范围的最大字体大小。我使用 boundingRectWithSize。我假设一旦它给我一个大于我的 testRe
非常简单的问题,我正在尝试动态获取 UILabel 的高度,而且 boundingRectWithSize:options:context: 似乎忽略了我的第二行。我在下面粘贴了相关代码: CGSiz
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
我在项目中的要求是UITextView的字体大小应该根据UITextView的内容减小。所以我正在尝试使用 boundingRectWithSize 来估计文本的大小。 问题是我得到的字体大小有点太大
当使用 [NSString boundingRectWithSize:options:attributes] 时,对于某些字符串,返回的矩形的大小比我预期的要高。返回的高度似乎表示具有给定属性的字符串
我查看了几个 Stackoverflow 问题,其中人们对 boundingRectWithSize 有问题,但没有一个是我的问题。 下面的代码通常计算出 1 行文本太高的高度。 CGFloat he
我想要一个 UILabel,其中部分文本带有下划线以类似于链接。这就是我构建 NSAttributedString 的方式: let attributedStr = NSMutableAttribut
[text boundingRectWithSize:BOLIVIASize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NS
我正在尝试使用以下代码动态更新 UITextView 的高度,但结果始终偏离几个像素,这导致 TextView 换行但大小不合适。输入另一个(或两个)字符后,显示会相应更新。 我查看了各种帖子(许多帖
需要 UITextView 所需的高度。 sizeThatFits 返回比 boundingRectWithSize 更大但正确的高度。为什么会存在差异? 在两个地方我需要知道高度。在 cellFor
我有两个 UILabels L1 和 L2。 L1最大宽度为150 L1的最小宽度会根据文字长度调整 两个标签之间的距离是10。 我的代码, NSString *s = @"Stringwithout
我正在尝试根据其当前宽度自动调整文本字段/ View 的大小。换句话说,我希望宽度保持不变,但根据提供给它的文本调整高度。 它似乎工作正常,但出于某种原因,尽管已努力将其移回,但它仍与我的窗口底部对齐
我正在尝试获取属性字符串的矩形,但 boundingRectWithSize 调用不尊重我传入的大小,并返回一个具有单行高度而不是大高度的矩形(它是一个长字符串) .我已经通过传入一个非常大的高度值和
在 iOS7 中,sizeWithFont 已被弃用,所以我使用 boundingRectWithSize(它返回一个 CGRect 值)。我的代码: UIFont *fontText = [UIF
我是一名优秀的程序员,十分优秀!