如何在 UITextView 中设置文本的字体大小以使其填充整个 UITextView?我希望用户输入他们的文本,然后让文本填充整个 UITextView。
任何帮助表示赞赏!
如何在 UITextView 中设置文本的字体大小以使其填充整个 UITextView?我希望用户输入他们的文本,然后让文本填充整个 UITextView。
任何帮助表示赞赏!
我已将痴呆症的答案转换为 Swift:
func updateTextFont() {
if (textView.text.isEmpty || CGSizeEqualToSize(textView.bounds.size, CGSizeZero)) {
return;
}
let textViewSize = textView.frame.size;
let fixedWidth = textViewSize.width;
let expectSize = textView.sizeThatFits(CGSizeMake(fixedWidth, CGFloat(MAXFLOAT)));
var expectFont = textView.font;
if (expectSize.height > textViewSize.height) {
while (textView.sizeThatFits(CGSizeMake(fixedWidth, CGFloat(MAXFLOAT))).height > textViewSize.height) {
expectFont = textView.font!.fontWithSize(textView.font!.pointSize - 1)
textView.font = expectFont
}
}
else {
while (textView.sizeThatFits(CGSizeMake(fixedWidth, CGFloat(MAXFLOAT))).height < textViewSize.height) {
expectFont = textView.font;
textView.font = textView.font!.fontWithSize(textView.font!.pointSize + 1)
}
textView.font = expectFont;
}
}
斯威夫特 3.0+ 更新:
func updateTextFont() {
if (textView.text.isEmpty || textView.bounds.size.equalTo(CGSize.zero)) {
return;
}
let textViewSize = textView.frame.size;
let fixedWidth = textViewSize.width;
let expectSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT)));
var expectFont = textView.font;
if (expectSize.height > textViewSize.height) {
while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height > textViewSize.height) {
expectFont = textView.font!.withSize(textView.font!.pointSize - 1)
textView.font = expectFont
}
}
else {
while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height < textViewSize.height) {
expectFont = textView.font;
textView.font = textView.font!.withSize(textView.font!.pointSize + 1)
}
textView.font = expectFont;
}
}
这在 UITextView 的一个类别中应该可以解决问题。为什么需要 fudgefactor,请参阅这篇文章
#define kMaxFieldHeight 9999
-(BOOL)sizeFontToFit:(NSString*)aString minSize:(float)aMinFontSize maxSize:(float)aMaxFontSize
{
float fudgeFactor = 16.0;
float fontSize = aMaxFontSize;
self.font = [self.font fontWithSize:fontSize];
CGSize tallerSize = CGSizeMake(self.frame.size.width-fudgeFactor,kMaxFieldHeight);
CGSize stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
while (stringSize.height >= self.frame.size.height)
{
if (fontSize <= aMinFontSize) // it just won't fit
return NO;
fontSize -= 1.0;
self.font = [self.font fontWithSize:fontSize];
tallerSize = CGSizeMake(self.frame.size.width-fudgeFactor,kMaxFieldHeight);
stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
}
return YES;
}
与 Arie Litovsky 的答案类似的方法,但没有子分类(或使用类别)并且没有使用contentSize
which 并没有为我返回渲染文本的正确高度。在 iOS 7 上测试:
while (((CGSize) [_textView sizeThatFits:_textView.frame.size]).height > _textView.frame.size.height) {
_textView.font = [_textView.font fontWithSize:_textView.font.pointSize-1];
}
方法是不断减小字体大小,直到文本刚好适合文本视图的框架。
如果您要在生产中使用它,您仍然需要:
试试这个,它更简单:
while (self.contentSize.height > self.frame.size.height)
{
self.font = [self.font fontWithSize:self.font.pointSize -1];
[self layoutSubviews];//force .contentSize to update
}
这是我的示例代码。基本上,我检查期望大小以了解字体大小是否需要增加或减少。您需要将 UITextViewDelegate 添加到您的课程中以确保其正常工作
- (void)updateTextFont:(UITextView *)textView
{
// Only run if has text, otherwise it will make infinity loop
if (textView.text.length == 0 || CGSizeEqualToSize(textView.bounds.size, CGSizeZero)) return;
/*
- Update textView font size
If expectHeight > textViewHeight => descrease font size n point until it reach textViewHeight
If expectHeight < textViewHeight => inscrease font size n point until it reach textViewHeight
*/
CGSize textViewSize = textView.frame.size;
CGFloat fixedWidth = textViewSize.width;
CGSize expectSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
UIFont *expectFont = textView.font;
if (expectSize.height > textViewSize.height) {
while ([textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)].height > textViewSize.height) {
expectFont = [textView.font fontWithSize:(textView.font.pointSize-1)];
textView.font = expectFont;
}
} else {
while ([textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)].height < textViewSize.height) {
expectFont = textView.font;
textView.font = [textView.font fontWithSize:(textView.font.pointSize+1)];
}
textView.font = expectFont;
}
}
我已将痴呆症和马特弗雷尔对 Swift 3 的回答转换为:
func updateTextFont() {
if (textView.text.isEmpty || textView.bounds.size.equalTo(CGSize.zero)) {
return
}
let textViewSize = textView.frame.size
let fixedWidth = textViewSize.width
let expectSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT)))
var expectFont = textView.font
if (expectSize.height > textViewSize.height) {
while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height > textViewSize.height) {
expectFont = textView.font!.withSize(textView.font!.pointSize - 1)
textView.font = expectFont
}
}
else {
while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height < textViewSize.height) {
expectFont = textView.font
textView.font = textView.font!.withSize(textView.font!.pointSize + 1)
}
textView.font = expectFont
}
}
快速 3
func updateTextFont(textView: UITextView) {
if (textView.text.isEmpty || textView.bounds.size.equalTo(CGSize.zero)) {
return
}
let textViewSize = textView.frame.size
let fixedWidth = textViewSize.width
let expectSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT)))
var expectFont = textView.font;
if (expectSize.height > textViewSize.height) {
while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height > textViewSize.height) {
expectFont = textView.font!.withSize(textView.font!.pointSize - 1)
textView.font = expectFont
}
}
else {
while (textView.sizeThatFits(CGSize(width: fixedWidth,height: CGFloat(MAXFLOAT))).height < textViewSize.height) {
expectFont = textView.font
textView.font = textView.font!.withSize(textView.font!.pointSize + 1)
}
textView.font = expectFont
}
}
此属性仅在 UITextFields 上可用。要在 UITextView 中执行此操作,您必须不断观察文本并在更改时手动调整字体大小。
我已将 Matt Frear 的答案转换为 Swift 4.1 作为 UITextView 的扩展:
extension UITextView {
func updateTextFont() {
if (self.text.isEmpty || self.bounds.size.equalTo(CGSize.zero)) {
return;
}
let textViewSize = self.frame.size;
let fixedWidth = textViewSize.width;
let expectSize = self.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT)))
var expectFont = self.font
if (expectSize.height > textViewSize.height) {
while (self.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height > textViewSize.height) {
expectFont = self.font!.withSize(self.font!.pointSize - 1)
self.font = expectFont
}
}
else {
while (self.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height < textViewSize.height) {
expectFont = self.font
self.font = self.font!.withSize(self.font!.pointSize + 1)
}
self.font = expectFont
}
}
}
希望这更清楚:
extension UITextView {
@objc public func fitText() {
fitText(into: frame.size)
}
@objc public func fitText(into originalSize: CGSize) {
let originalWidth = originalSize.width
let expectedSize = sizeThatFits(CGSize(width: originalWidth, height: CGFloat(MAXFLOAT)))
if expectedSize.height > originalSize.height {
while let font = self.font, sizeThatFits(CGSize(width: originalWidth, height: CGFloat(MAXFLOAT))).height > originalSize.height {
self.font = font.withSize(font.pointSize - 1)
}
} else {
var previousFont = self.font
while let font = self.font, sizeThatFits(CGSize(width: originalWidth, height: CGFloat(MAXFLOAT))).height < originalSize.height {
previousFont = font
self.font = font.withSize(font.pointSize + 1)
}
self.font = previousFont
}
}
}
在 viewDidLoad 中:
textView.textContainer.lineFragmentPadding = 0;
textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
您需要添加 UITextViewDelegate:
- (void)updateTextFont:(UITextView *)textView {
CGSize textViewSize = textView.frame.size;
CGSize sizeOfText = [textView.text sizeWithAttributes:@{NSFontAttributeName: textView.font}];
CGFloat fontOfWidth = floorf(textView.font.pointSize / sizeOfText.height * textViewSize.height);
CGFloat fontOfHeight = floorf(textView.font.pointSize / sizeOfText.width * textViewSize.width);
textView.font = [textView.font fontWithSize:MIN(fontOfHeight, fontOfWidth)];
}
@Arie Litovsky 代码的更新版本。这适用于 iOS7 及更高版本,并向上和向下拉伸字体大小以使文本适合。
- (void) stretchFontToFit:(UITextView*)textView
{
while( textView.contentSize.height < textView.frame.size.height )
{
textView.font = [textView.font fontWithSize:textView.font.pointSize +1];
[textView layoutIfNeeded];
}
while( textView.contentSize.height > textView.frame.size.height )
{
textView.font = [textView.font fontWithSize:textView.font.pointSize -1];
[textView layoutIfNeeded];
}
}
这是痴呆症和马特弗雷尔对 Swift 5 的回答的转换。将此函数放入 viewDidLayoutSubviews,引用 UITextView 的要动态调整大小的字体。
func updateTextFont(textView: UITextView) {
if (textView.text.isEmpty || textView.bounds.size.equalTo(CGSize.zero)) {
return;
}
let textViewSize = textView.frame.size;
let fixedWidth = textViewSize.width;
let expectSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT)))
var expectFont = textView.font;
if (expectSize.height > textViewSize.height) {
while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height > textViewSize.height) {
expectFont = textView.font!.withSize(textView.font!.pointSize - 1)
textView.font = expectFont
}
}
else {
while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height < textViewSize.height) {
expectFont = textView.font;
textView.font = textView.font!.withSize(textView.font!.pointSize + 1)
}
textView.font = expectFont;
}
}
你可以通过使用轻松做到这一点
self.textview.font
= self.textview.font = UIFont(名称:self.textview.font!.fontName,
大小:self.textview.frame.size.height / 10)!
根据您的要求将 textview.frame.size.height 划分为某个常数..
这是Swift 4的解决方案(基于Arie Litovsky的回答),您可以将此代码放入textViewDidChange(_ textView: UITextView)
委托方法中:
缩小字体:
while (textView.contentSize.height > textView.frame.size.height) {
guard let fontName = textView.font?.fontName, let fontSize = textView.font?.pointSize else {return}
if fontSize < 12 {
return
}
textView.font = UIFont(name: fontName, size: fontSize - 1)
textView.layoutIfNeeded()
}
并放大字体:
while (textView.contentSize.height < textView.frame.size.height) {
guard let fontName = textView.font?.fontName, let fontSize = textView.font?.pointSize else {return}
if fontSize > 15 {
return
}
textView.font = UIFont(name: fontName, size: fontSize + 1)
textView.layoutIfNeeded()
}
您可以更改fontSize < 12
和fontSize > 15
以满足您的最小和最大字体大小的需求。