13

如何在 UITextView 中设置文本的字体大小以使其填充整个 UITextView?我希望用户输入他们的文本,然后让文本填充整个 UITextView。

任何帮助表示赞赏!

4

15 回答 15

22

我已将痴呆症的答案转换为 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;
    }
}
于 2014-11-24T22:26:56.033 回答
8

这在 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; 
}
于 2010-05-31T11:56:11.723 回答
7

与 Arie Litovsky 的答案类似的方法,但没有子分类(或使用类别)并且没有使用contentSizewhich 并没有为我返回渲染文本的正确高度。在 iOS 7 上测试:

while (((CGSize) [_textView sizeThatFits:_textView.frame.size]).height > _textView.frame.size.height) {
    _textView.font = [_textView.font fontWithSize:_textView.font.pointSize-1];
}

方法是不断减小字体大小,直到文本刚好适合文本视图的框架。

如果您要在生产中使用它,您仍然需要:

  • 处理即使使用最小可能字体大小文本仍然不适合的情况。
  • 如果您还想放大文本以适应框架,请使用类似的方法来增加字体大小。
于 2014-03-16T11:01:00.823 回答
6

试试这个,它更简单:

while (self.contentSize.height > self.frame.size.height)
{
    self.font = [self.font fontWithSize:self.font.pointSize -1];
    [self layoutSubviews];//force .contentSize to update
}
于 2012-08-06T19:56:16.670 回答
3

这是我的示例代码。基本上,我检查期望大小以了解字体大小是否需要增加或减少。您需要将 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;
    }
}
于 2014-07-22T10:31:10.420 回答
3

我已将痴呆症和马特弗雷尔对 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
    }
}
于 2017-01-13T11:41:01.507 回答
3

快速 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
     }
 }
于 2017-07-25T12:47:56.150 回答
2

此属性仅在 UITextFields 上可用。要在 UITextView 中执行此操作,您必须不断观察文本并在更改时手动调整字体大小。

于 2010-01-11T01:20:02.610 回答
2

我已将 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
    }
}
}
于 2018-04-21T12:36:05.663 回答
2

希望这更清楚:

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
        }
    }
}
于 2019-11-22T09:55:02.293 回答
1

在 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)];
}
于 2016-12-29T16:39:50.807 回答
0

@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];
    }
}
于 2016-05-31T15:25:25.950 回答
0

这是痴呆症马特弗雷尔对 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;
    }
}
于 2019-08-04T04:13:13.907 回答
-1

你可以通过使用轻松做到这一点

  • self.textview.font=

self.textview.font = UIFont(名称:self.textview.font!.fontName,
大小:self.textview.frame.size.height / 10)!

根据您的要求将 textview.frame.size.height 划分为某个常数..

于 2017-05-30T22:47:31.537 回答
-2

这是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 < 12fontSize > 15以满足您的最小和最大字体大小的需求。

于 2018-01-30T09:55:43.587 回答