545

有没有一种好方法可以调整 a 的大小UITextView以符合其内容?比如说我有一个UITextView包含一行文本的:

"Hello world"

然后我添加另一行文本:

"Goodbye world"

在 Cocoa Touch 中是否有一种好方法可以让rect文本视图中的所有行都保持不变,以便我可以相应地调整父视图?

作为另一个示例,查看日历应用程序中事件的便笺字段 - 请注意单元格(及其UITextView包含的单元格)如何扩展以容纳便笺字符串中的所有文本行。

4

41 回答 41

638

这适用于 iOS 6.1 和 iOS 7:

- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    textView.frame = newFrame;
}

或在 Swift 中(适用于 iOS 11 中的 Swift 4.1)

let fixedWidth = textView.frame.size.width
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)

如果您想要支持 iOS 6.1,那么您还应该:

textview.scrollEnabled = NO;
于 2013-09-21T10:26:20.690 回答
579

这不再适用于 iOS 7 或更高版本

实际上有一种非常简单的方法可以UITextView将其大小调整到正确的内容高度。可以使用UITextView contentSize.

CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

需要注意的一件事是,正确的contentSize只有在使用 .添加到视图后才可用。在此之前它等于UITextViewaddSubviewframe.size

如果自动布局打开,这将不起作用。使用自动布局,一般方法是使用该sizeThatFits方法并更新constant高度约束上的值。

CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.frame.size];
heightConstraint.constant = sizeThatShouldFitTheContent.height;

heightConstraint是一个布局约束,您通常通过 IBOutlet 将属性链接到情节提要中创建的高度约束来设置。


只是为了增加这个惊人的答案,2014,如果你:

[self.textView sizeToFit];

仅iPhone6+的行为有所不同:

在此处输入图像描述

仅使用 6+(不是 5s 或 6)它确实向 UITextView 添加了“一个空白行”。“RL 解决方案”完美地解决了这个问题:

CGRect _f = self.mainPostText.frame;
_f.size.height = self.mainPostText.contentSize.height;
self.mainPostText.frame = _f;

它修复了 6+ 的“额外行”问题。

于 2010-03-21T14:26:31.360 回答
102

更新

您需要做的关键事情是关闭 UITextView 中的滚动。

myTextView.scrollEnabled = @NO

原始答案

为了在 a 中动态调整大小UITextViewUITableViewCell我发现以下组合适用于 Xcode 6 和 iOS 8 SDK:

  • 将 a 添加UITextView到 aUITableViewCell并将其约束到两侧

  • UITextView'scrollEnabled属性设置为NO。启用滚动后,框架UITextView与其内容大小无关,但禁用滚动时,两者之间存在关系。

  • 如果您的表格使用 44 的原始默认行高,那么它将自动计算行高,但如果您将默认行高更改为其他值,您可能需要手动打开行高的自动计算viewDidLoad

     tableView.estimatedRowHeight = 150;
     tableView.rowHeight = UITableViewAutomaticDimension;
    

对于只读动态调整UITextViews,就是这样。如果您允许用户编辑 中的文本UITextView,您还需要:

  • 实现协议的textViewDidChange:方法UITextViewDelegate,并告诉tableView每次编辑文本时重新绘制自己:

     - (void)textViewDidChange:(UITextView *)textView;
     {
         [tableView beginUpdates];
         [tableView endUpdates];
     }
    
  • 并且不要忘记将UITextView委托设置在某个地方,无论是 inStoryboard还是 intableView:cellForRowAtIndexPath:

于 2014-10-28T01:12:15.390 回答
93

使用代码和故事板的非常简单的工作解决方案。

按代码

textView.scrollEnabled = false

通过故事板

取消选中滚动启用

在此处输入图像描述

除此以外无需做任何事情。

于 2016-07-17T07:06:09.627 回答
64

斯威夫特:

textView.sizeToFit()
于 2015-10-01T18:32:46.387 回答
24

在我的(有限的)经验中,

- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode

不尊重换行符,因此您最终可能会CGSize比实际需要的要短得多。

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

似乎确实尊重换行符。

此外,文本实际上并未呈现在UITextView. 在我的代码中,我将 的新高度设置为UITextViewsizeOfFont方法返回的高度大 24 像素。

于 2009-02-08T19:01:43.873 回答
24

在 iOS6 中,您可以contentSize在设置文本后立即检查 UITextView 的属性。在 iOS7 中,这将不再起作用。如果要在 iOS7 中恢复此行为,请将以下代码放在 UITextView 的子类中。

- (void)setText:(NSString *)text
{
    [super setText:text];

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        CGRect rect = [self.textContainer.layoutManager usedRectForTextContainer:self.textContainer];
        UIEdgeInsets inset = self.textContainerInset;
        self.contentSize = UIEdgeInsetsInsetRect(rect, inset).size;
    }
}
于 2013-09-16T21:35:08.990 回答
19

我将在页面底部发布正确的解决方案,以防有人勇敢(或绝望)阅读到这一点。

对于那些不想阅读所有文本的人来说,这里是 gitHub 存储库:resizableTextView

这适用于 iOs7(我相信它适用于 iOs8)和自动布局。你不需要幻数,禁用布局和类似的东西。简短而优雅的解决方案。

我认为,所有与约束相关的代码都应该转到updateConstraints方法。所以,让我们自己制作ResizableTextView.

我们在这里遇到的第一个问题是在方法之前不知道真实的内容大小viewDidLoad。我们可以根据字体大小、换行符等来计算它。但是我们需要强大的解决方案,所以我们会这样做:

CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];

所以现在我们知道真正的 contentSize 无论我们在哪里: before 或 after viewDidLoad。现在在 textView 上添加高度约束(通过故事板或代码,无论如何)。我们将使用以下方法调整该值contentSize.height

[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
    if (constraint.firstAttribute == NSLayoutAttributeHeight) {
        constraint.constant = contentSize.height;
        *stop = YES;
    }
}];

最后要做的就是告诉超类到updateConstraints.

[super updateConstraints];

现在我们的类看起来像:

可调整大小的TextView.m

- (void) updateConstraints {
    CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];

    [self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
        if (constraint.firstAttribute == NSLayoutAttributeHeight) {
            constraint.constant = contentSize.height;
            *stop = YES;
        }
    }];

    [super updateConstraints];
}

漂亮干净,对吧?而且您不必在控制器中处理该代码!

可是等等! 没有动画!

您可以轻松地为更改设置动画以textView平滑拉伸。这是一个例子:

    [self.view layoutIfNeeded];
    // do your own text change here.
    self.infoTextView.text = [NSString stringWithFormat:@"%@, %@", self.infoTextView.text, self.infoTextView.text];
    [self.infoTextView setNeedsUpdateConstraints];
    [self.infoTextView updateConstraintsIfNeeded];
    [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];
于 2014-07-25T07:32:55.927 回答
14

你试过了[textView sizeThatFits:textView.bounds]吗?

编辑: sizeThatFits 返回大小,但实际上并没有调整组件的大小。我不确定这是否是您想要的,或者是否[textView sizeToFit]是您正在寻找的更多。无论哪种情况,我都不知道它是否完全符合您想要的内容,但这是首先要尝试的。

于 2008-09-08T20:36:56.947 回答
10

另一种方法是使用以下方法查找特定字符串将占用的大小NSString

-(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

这将返回适合给定字符串和给定字体的矩形的大小。传入具有所需宽度和最大高度的尺寸,然后您可以查看返回的高度以适合文本。有一个版本还可以让您指定换行模式。

然后,您可以使用返回的大小来更改视图的大小以适应。

于 2008-09-20T06:19:17.460 回答
9

我们可以通过约束来做到这一点。

  1. 为 UITextView 设置高度约束。 在此处输入图像描述

2.为该高度约束创建 IBOutlet。

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *txtheightconstraints;

3.不要忘记为您的文本视图设置委托。

4.

-(void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    NSLog(@"this is updating height%@",NSStringFromCGSize(newFrame.size));
    [UIView animateWithDuration:0.2 animations:^{
                  _txtheightconstraints.constant=newFrame.size.height;
    }];

}

然后像这样更新你的约束:)

于 2016-03-04T07:16:20.687 回答
8

如果您没有UITextView方便(例如,您正在调整表格视图单元格的大小),则必须通过测量字符串来计算大小,然后计算 a 每一侧的 8 pt 填充UITextView。例如,如果您知道文本视图所需的宽度并想计算出相应的高度:

NSString * string = ...;
CGFloat textViewWidth = ...;
UIFont * font = ...;

CGSize size = CGSizeMake(textViewWidth - 8 - 8, 100000);
size.height = [string sizeWithFont:font constrainedToSize:size].height + 8 + 8;

在这里,每个 8 占四个填充边缘之一,而 100000 只是作为一个非常大的最大尺寸。

在实践中,您可能希望font.leading在高度上增加一个额外的值;这会在您的文本下方添加一个空白行,如果文本视图正下方有视觉上沉重的控件,这可能会更好看。

于 2012-10-24T11:20:18.257 回答
8

从 iOS 8 开始,可以使用 UITableView 的自动布局功能来自动调整 UITextView 的大小,而无需任何自定义代码。我在github中放了一个项目来演示这一点,但这里是关键:

  1. UITextView 必须禁用滚动,您可以通过编程方式或通过界面生成器执行此操作。如果启用滚动,它不会调整大小,因为滚动可以让您查看更大的内容。
  2. 在 UITableViewController 的 viewDidLoad 中,您必须为 estimatedRowHeight 设置一个值,然后将其设置rowHeightUITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. 项目部署目标必须是 iOS 8 或更高版本。
于 2015-06-04T17:41:49.917 回答
7

结合迈克麦克马斯特的回答,您可能想要执行以下操作:

[myTextView setDelegate: self];

...

- (void)textViewDidChange:(UITextView *)textView {
  if (myTextView == textView) {
     // it changed.  Do resizing here.
  }
}
于 2008-11-06T04:31:12.733 回答
7

我找到了一种方法来根据其中的文本调整文本字段的高度,并根据文本字段的高度在其下方排列一个标签!这是代码。

UITextView *_textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 300, 10)];
NSString *str = @"This is a test text view to check the auto increment of height of a text view. This is only a test. The real data is something different.";
_textView.text = str;

[self.view addSubview:_textView];
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 5 + frame.origin.y + frame.size.height, 300, 20)];
lbl.text = @"Hello!";
[self.view addSubview:lbl];
于 2011-03-14T10:13:32.440 回答
7

使用自动布局的人并且您的 sizetofit 不起作用,那么请检查您的宽度限制一次。如果您错过了宽度限制,那么高度将是准确的。

无需使用任何其他 API。只需一行就可以解决所有问题。

[_textView sizeToFit];

在这里,我只关心高度,保持宽度固定,并错过了我的 TextView 在情节提要中的宽度约束。

这是为了显示来自服务的动态内容。

希望这可能会有所帮助..

于 2015-01-02T06:58:22.503 回答
7

以下内容就足够了:

  1. 只需记住将启用的滚动设置为NOUITextView

在此处输入图像描述

  1. 正确设置自动布局约束。

你甚至可以使用UITableViewAutomaticDimension.

于 2015-11-02T10:18:23.187 回答
6

我查看了所有答案,所有答案都保持固定宽度并仅调整高度。如果你想调整宽度,你可以很容易地使用这个方法:

所以在配置你的文本视图时,设置滚动禁用

textView.isScrollEnabled = false

然后在委托方法中func textViewDidChange(_ textView: UITextView)添加以下代码:

func textViewDidChange(_ textView: UITextView) {
    let newSize = textView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
    textView.frame = CGRect(origin: textView.frame.origin, size: newSize)
}

输出:

在此处输入图像描述

在此处输入图像描述

于 2017-03-21T13:38:27.150 回答
6

使用 UITextViewDelegate 是最简单的方法:

func textViewDidChange(_ textView: UITextView) {
    textView.sizeToFit()
    textviewHeight.constant = textView.contentSize.height
}
于 2020-02-27T18:14:37.637 回答
5

禁用滚动

添加约束

并添加您的文字

[yourTextView setText:@"your text"];
[yourTextView layoutIfNeeded];

如果你使用UIScrollView你也应该添加这个;

[yourScrollView layoutIfNeeded];

-(void)viewDidAppear:(BOOL)animated{
    CGRect contentRect = CGRectZero;

    for (UIView *view in self.yourScrollView.subviews) {
         contentRect = CGRectUnion(contentRect, view.frame);
    }
    self.yourScrollView.contentSize = contentRect.size;
}
于 2018-01-10T13:06:48.600 回答
4

当我需要使文本UITextView适合特定区域时,这很有效:

// 文本必须已经添加到子视图中,否则 contentviewsize 会出错。

- (void) reduceFontToFit: (UITextView *)tv {
    UIFont *font = tv.font;
    双pointSize = font.pointSize;

    而(tv.contentSize.height > tv.frame.size.height && pointSize > 7.0){
        点大小-= 1.0;
        UIFont *newFont = [UIFont fontWithName:font.fontName size:pointSize];
        tv.font = 新字体;
    }
    if (pointSize != font.pointSize)
        NSLog(@"font down to %.1f from %.1f", pointSize, tv.font.pointSize);
}
于 2012-10-08T17:59:10.417 回答
4

这是@jhibberd 的快速版本

    let cell:MsgTableViewCell! = self.tableView.dequeueReusableCellWithIdentifier("MsgTableViewCell", forIndexPath: indexPath) as? MsgTableViewCell
    cell.msgText.text = self.items[indexPath.row]
    var fixedWidth:CGFloat = cell.msgText.frame.size.width
    var size:CGSize = CGSize(width: fixedWidth,height: CGFloat.max)
    var newSize:CGSize = cell.msgText.sizeThatFits(size)
    var newFrame:CGRect = cell.msgText.frame;
    newFrame.size = CGSizeMake(CGFloat(fmaxf(Float(newSize.width), Float(fixedWidth))), newSize.height);
    cell.msgText.frame = newFrame
    cell.msgText.frame.size = newSize        
    return cell
于 2015-03-07T16:02:09.333 回答
3

对于 iOS 7.0,不要将 设置frame.size.heightcontentSize.height(目前什么都不做)使用[textView sizeToFit].

看到这个问题

于 2013-09-20T02:39:00.403 回答
3

这适用于Swift 5,以防您希望在用户即时编写文本后适应您的 TextView。

只需使用以下方法实现UITextViewDelegate

func textViewDidChange(_ textView: UITextView) {
    let newSize = textView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
    textView.frame.size = CGSize(width: newSize.width, height: newSize.height)
}
于 2019-12-09T13:45:52.267 回答
2

如果有其他人到这里,这个解决方案对我有用,1“Ronnie Liew”+4“user63934”(我的文本来自网络服务):注意 1000(“在我的情况下”没有什么可以这么大)

UIFont *fontNormal = [UIFont fontWithName:FONTNAME size:FONTSIZE];

NSString *dealDescription = [client objectForKey:@"description"];

//4
CGSize textSize = [dealDescription sizeWithFont:fontNormal constrainedToSize:CGSizeMake(containerUIView.frame.size.width, 1000)];

CGRect dealDescRect = CGRectMake(10, 300, containerUIView.frame.size.width, textSize.height);

UITextView *dealDesc = [[[UITextView alloc] initWithFrame:dealDescRect] autorelease];

dealDesc.text = dealDescription;
//add the subview to the container
[containerUIView addSubview:dealDesc];

//1) after adding the view
CGRect frame = dealDesc.frame;
frame.size.height = dealDesc.contentSize.height;
dealDesc.frame = frame;

那就是……干杯

于 2012-07-30T01:56:34.430 回答
1

希望这可以帮助:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}
于 2010-03-17T17:31:32.510 回答
1

我发现根据文本大小重新调整 UITextView 高度的最佳方法。

CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0]
                       constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX)];

或者你可以使用

CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0]
                       constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX) lineBreakMode:NSLineBreakByTruncatingTail];
于 2013-09-06T06:27:03.373 回答
1

对于那些希望 textview 实际向上移动并保持底线位置的人

CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;

if(frame.size.height > textView.frame.size.height){
    CGFloat diff = frame.size.height - textView.frame.size.height;
    textView.frame = CGRectMake(0, textView.frame.origin.y - diff, textView.frame.size.width, frame.size.height);
}
else if(frame.size.height < textView.frame.size.height){
    CGFloat diff = textView.frame.size.height - frame.size.height;
    textView.frame = CGRectMake(0, textView.frame.origin.y + diff, textView.frame.size.width, frame.size.height);
}
于 2014-11-30T21:43:46.880 回答
1

唯一可以使用的代码是在上面的 jhibberd 答案中使用“SizeToFit”的代码,但实际上除非您在ViewDidAppear中调用它或将其连接到 UITextView 文本更改事件,否则它不会启动。

于 2015-04-08T08:25:57.160 回答
1

根据 Nikita Take 的回答,我在 Swift 中找到了以下解决方案,该解决方案适用于具有自动布局的 iOS 8:

    descriptionTxt.scrollEnabled = false
    descriptionTxt.text = yourText

    var contentSize = descriptionTxt.sizeThatFits(CGSizeMake(descriptionTxt.frame.size.width, CGFloat.max))
    for c in descriptionTxt.constraints() {
        if c.isKindOfClass(NSLayoutConstraint) {
            var constraint = c as! NSLayoutConstraint
            if constraint.firstAttribute == NSLayoutAttribute.Height {
                constraint.constant = contentSize.height
                break
            }
        }
    }
于 2015-05-13T12:46:46.857 回答
1

快速回答:以下代码计算 textView 的高度。

                let maximumLabelSize = CGSize(width: Double(textView.frame.size.width-100.0), height: DBL_MAX)
                let options = NSStringDrawingOptions.TruncatesLastVisibleLine | NSStringDrawingOptions.UsesLineFragmentOrigin
                let attribute = [NSFontAttributeName: textView.font!]
                let str = NSString(string: message)
                let labelBounds = str.boundingRectWithSize(maximumLabelSize,
                    options: NSStringDrawingOptions.UsesLineFragmentOrigin,
                    attributes: attribute,
                    context: nil)
                let myTextHeight = CGFloat(ceilf(Float(labelBounds.height)))

现在您可以将 textView 的高度设置为myTextHeight

于 2015-05-16T23:16:38.437 回答
1

如果您需要调整大小textViewtableViewCell动态调整,这是答案staticTableView

[ https://stackoverflow.com/a/43137182/5360675][1]

于 2017-03-31T09:39:19.337 回答
1

像 ios 11 上的魅力一样工作,我在一个单元格中工作,就像一个带有气泡的聊天单元格。

let content = UITextView(frame: CGRect(x: 4, y: 4, width: 0, height: 0))
content.text = "what ever short or long text you wanna try"
content.textAlignment = NSTextAlignment.left
content.font = UIFont.systemFont(ofSize: 13)
let spaceAvailable = 200 //My cell is fancy I have to calculate it...
let newSize = content.sizeThatFits(CGSize(width: CGFloat(spaceAvailable), height: CGFloat.greatestFiniteMagnitude))
content.isEditable = false
content.dataDetectorTypes = UIDataDetectorTypes.all
content.isScrollEnabled = false
content.backgroundColor = UIColor.clear
bkgView.addSubview(content)
于 2017-09-25T06:04:48.640 回答
0

这种方法似乎适用于 ios7

 // Code from apple developer forum - @Steve Krulewitz, @Mark Marszal, @Eric Silverberg
- (CGFloat)measureHeight
{
    if ([self respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)])
    {
    CGRect frame = internalTextView.bounds;
    CGSize fudgeFactor;
    // The padding added around the text on iOS6 and iOS7 is different.
    fudgeFactor = CGSizeMake(10.0, 16.0);

    frame.size.height -= fudgeFactor.height;
    frame.size.width -= fudgeFactor.width;

    NSMutableAttributedString* textToMeasure;
    if(internalTextView.attributedText && internalTextView.attributedText.length > 0){
        textToMeasure = [[NSMutableAttributedString alloc] initWithAttributedString:internalTextView.attributedText];
    }
    else{
        textToMeasure = [[NSMutableAttributedString alloc] initWithString:internalTextView.text];
        [textToMeasure addAttribute:NSFontAttributeName value:internalTextView.font range:NSMakeRange(0, textToMeasure.length)];
    }

    if ([textToMeasure.string hasSuffix:@"\n"])
    {
        [textToMeasure appendAttributedString:[[NSAttributedString alloc] initWithString:@"-" attributes:@{NSFontAttributeName: internalTextView.font}]];
    }

    // NSAttributedString class method: boundingRectWithSize:options:context is
    // available only on ios7.0 sdk.
    CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                              context:nil];

    return CGRectGetHeight(size) + fudgeFactor.height;
}
else
{
    return self.internalTextView.contentSize.height;
}
}
于 2013-09-29T22:56:33.403 回答
0

询问 a 的最简单方法UITextView是调用-sizeToFit它也应该与 一起使用scrollingEnabled = YES,然后检查高度并在文本视图上添加具有相同值的高度约束。
注意UITexView包含插入,这意味着您不能询问字符串对象要使用多少空间,因为这只是文本的边界矩形。
所有使用它的人都遇到错误的大小-sizeToFit可能是由于文本视图尚未布局到界面大小。
当您使用 size classes 和 a 时,总是会发生这种情况UITableView,第一次在- tableView:cellForRowAtIndexPath:带有任意配置的大小,如果您计算您刚才的值,文本视图将具有与预期不同的宽度,这将拧紧所有尺寸。
为了克服这个问题,我发现重写-layoutSubviews单元格的方法来重新计算 textview 高度很有用。

于 2015-10-22T07:41:30.153 回答
0

如果您正在使用滚动视图和内容视图,并且您想根据 TextView 内容高度增加高度,那么这段代码将对您有所帮助。

希望这会有所帮助,它在 iOS9.2 中完美运行

当然设置textview.scrollEnabled = NO;

-(void)adjustHeightOfTextView
{
    //this pieces of code will helps to adjust the height of the uitextview View W.R.T content
    //This block of code work will calculate the height of the textview text content height and calculate the height for the whole content of the view to be displayed.Height --> 400 is fixed,it will change if you change anything in the storybord.


CGSize textViewSize = [self.textview sizeThatFits:CGSizeMake(self.view.frame.size.width, self.view.frame.size.height)];//calulcate the content width and height

float textviewContentheight =textViewSize.height;
self.scrollview.contentSize = CGSizeMake(self.textview.frame.size.width,textviewContentheight + 400);//height value is passed
self.scrollview.frame =CGRectMake(self.scrollview.frame.origin.x, self.scrollview.frame.origin.y, self.scrollview.frame.size.width, textviewContentheight+400);

CGRect Frame = self.contentview.frame;
Frame.size.height = textviewContentheight + 400;
[self.contentview setFrame:Frame];

self.textview.frame =CGRectMake(self.textview.frame.origin.x, self.textview.frame.origin.y, self.textview.frame.size.width, textviewContentheight);
[ self.textview setContentSize:CGSizeMake( self.textview.frame.size.width,textviewContentheight)];
self.contenview_heightConstraint.constant = 

self.scrollview.bounds.size.height;
    NSLog(@"%f",self.contenview_heightConstraint.constant);
}
于 2016-01-24T11:31:24.127 回答
0

使用 Key Value Observing (KVO) 非常简单,只需创建 UITextView 的子类并执行以下操作:

private func setup() { // Called from init or somewhere

    fitToContentObservations = [
        textView.observe(\.contentSize) { _, _ in
            self.invalidateIntrinsicContentSize()
        },
        // For some reason the content offset sometimes is non zero even though the frame is the same size as the content size.
        textView.observe(\.contentOffset) { _, _ in
            if self.contentOffset != .zero { // Need to check this to stop infinite loop
                self.contentOffset = .zero
            }
        }
    ]
}
public override var intrinsicContentSize: CGSize {
    return contentSize
}

如果您不想子类化,可以尝试textView.bounds = textView.contentSizecontentSize观察者中进行。

于 2019-08-31T15:44:29.770 回答
0

对我有用的最简单的解决方案是在 Storyboard 中的 textView 上设置高度约束,然后将 textView 和高度约束连接到代码:

@IBOutlet var myAwesomeTextView: UITextView!
@IBOutlet var myAwesomeTextViewHeight: NSLayoutConstraint!

然后在设置文本和段落样式后,在viewDidAppear中添加:

self.myAwesomeTextViewHeight.constant = self.myAwesomeTextView.contentSize.height

一些注意事项:

  1. 与其他解决方案相比,必须将 isScrollEnabled 设置为 true才能使其正常工作。
  2. 就我而言,我正在为代码中的字体设置自定义属性,因此我必须在 viewDidAppear 中设置高度(在此之前它无法正常工作)。如果您没有在代码中更改任何文本属性,您应该能够在 viewDidLoad 或设置文本后的任何位置设置高度。
于 2021-02-17T21:11:02.667 回答
0

看起来这家伙为 NSTextView 想出来了,他的回答也适用于 iOS。原来intrinsicContentSize 不与布局管理器同步。如果在intrinsicContentSize 之后发生布局,您可能会有差异。

他有一个简单的解决办法。

NSOutlineView 中的 NSTextView 与 IntrinsicContentSize 设置错误的高度

于 2021-03-05T23:55:12.787 回答
-1

以下是步骤

解决方案适用于所有版本的 iOS。斯威夫特 3.0 及更高版本。

  1. 将您添加UITextViewView. 我正在使用代码添加它,您可以通过界面生成器添加。
  2. 添加约束。我在代码中添加了约束,你也可以在界面生成器中进行。
  3. 使用UITextViewDelegate方法func textViewDidChange(_ textView: UITextView)调整TextView的大小

代码 :

  1. //1. Add your UITextView in ViewDidLoad
    let textView = UITextView()
    textView.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
    textView.backgroundColor = .lightGray
    textView.text = "Here is some default text."
    
    
    
    //2. Add constraints
    textView.translatesAutoresizingMaskIntoConstraints = false
    [
    textView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
    textView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    textView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    textView.heightAnchor.constraint(equalToConstant: 50),
    textView.widthAnchor.constraint(equalToConstant: 30)
    ].forEach{ $0.isActive = true }
    
    textView.font = UIFont.preferredFont(forTextStyle: .headline)
    
    textView.delegate = self
    textView.isScrollEnabled = false
    
    textViewDidChange(textView)
    
    
    //3. Implement the delegate method.
    func textViewDidChange(_ textView: UITextView) {
    let size = CGSize(width: view.frame.width, height: .infinity)
    let estimatedSize = textView.sizeThatFits(size)
    
    textView.constraints.forEach { (constraint) in
        if constraint.firstAttribute == .height {
            print("Height: ", estimatedSize.height)
            constraint.constant = estimatedSize.height
        }
    }
    }
    
于 2018-07-19T06:48:17.263 回答
-3

不知道为什么人们总是把事情复杂化:这里是:

- (void)textViewDidChange:(UITextView *)textView{ CGRect frame = textView.frame;
CGFloat height = [self measureHeightOfUITextView:textView];
CGFloat insets = textView.textContainerInset.top + textView.textContainerInset.bottom;
height += insets;
frame.size.height = height;

if(frame.size.height > textView.frame.size.height){
    CGFloat diff = frame.size.height - textView.frame.size.height;
    textView.frame = CGRectMake(5, textView.frame.origin.y - diff, textView.frame.size.width, frame.size.height);
}
else if(frame.size.height < textView.frame.size.height){
    CGFloat diff = textView.frame.size.height - frame.size.height;
    textView.frame = CGRectMake(5, textView.frame.origin.y + diff, textView.frame.size.width, frame.size.height);
}
[textView setNeedsDisplay];
}
于 2014-12-23T17:31:17.380 回答