gpt4 book ai didi

ios - boundingRectWithSize 不复制 UITextView

转载 作者:可可西里 更新时间:2023-11-01 04:34:59 42 4
gpt4 key购买 nike

我在项目中的要求是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 只是我编写的一个自定义函数,它对 CGSizewidthheight 进行舍入到最近的 0.5

为了比较,如果您创建第二个 UITextView,并确保 textContainer.lineFragmentPaddingtextContainerInset 相同,您应该会看到这些值几乎与最接近的 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/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com