关于ios:如何根据内容调整UITextView的大小?

How do I size a UITextView to its content?

有没有一种很好的方法来调整UITextView的大小以符合其内容? 比方说我有一个包含一行文字的UITextView

1
"Hello world"

然后我添加另一行文字:

1
"Goodbye world"

在Cocoa Touch中有一个很好的方法来获取rect,它将保存文本视图中的所有行,以便我可以相应地调整父视图吗?

再举一个例子,查看日历应用程序中事件的注释字段 - 注意单元格(及其包含的UITextView)如何扩展以保存注释字符串中的所有文本行。


这适用于iOS 6.1和iOS 7:

1
2
3
4
5
6
7
8
- (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一起使用)

1
2
3
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,那么您还应该:

1
textview.scrollEnabled = NO;

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

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

1
2
3
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

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

如果自动布局为ON,则无效。对于自动布局,一般方法是使用sizeThatFits方法并更新高度约束上的constant值。

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

heightConstraint是一种布局约束,您通常通过将属性链接到故事板中创建的高度约束来设置IBOutlet。

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

1
[self.textView sizeToFit];

仅与iPhone6 +的行为有所不同:

enter image description here

只有6+(不是5s或6),它确实为UITextView增加了"一个空行"。"RL解决方案"完美地解决了这个问题:

1
2
3
CGRect _f = self.mainPostText.frame;
_f.size.height = self.mainPostText.contentSize.height;
self.mainPostText.frame = _f;

它修复了6+上的"额外线"问题。


要在UITableViewCell中生成动态调整大小UITextView,我发现以下组合在Xcode 6中与iOS 8 SDK一起使用:

  • UITextView添加到UITableViewCell并将其约束到两侧
  • UITextViewscrollEnabled属性设置为NO。启用滚动后,UITextView的框架与其内容大小无关,但在禁用滚动的情况下,两者之间存在关系。
  • 如果您的表使用原始默认行高44,那么它将自动计算行高,但如果您将默认行高更改为其他行,则可能需要在viewDidLoad中手动启用行高的自动计算:

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

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

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

    1
    2
    3
    4
    5
    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
  • 并且不要忘记在StoryboardtableView:cellForRowAtIndexPath:中将UITextView委托设置在某处


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

按代码

1
textView.scrollEnabled = false

通过故事板

取消选中滚动启用

enter image description here

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


斯威夫特:

1
textView.sizeToFit()

在我(有限)的经历中,

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

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

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

似乎确实尊重新线。

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


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

1
2
3
4
5
6
7
8
9
10
- (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;
    }
}

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

这里有gitHub repo,他们不想阅读所有文本:resizableTextView

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

我认为,所有与约束相关的代码都应该转到updateConstraints方法。那么,让我们自己创建ResizableTextView

我们在这里遇到的第一个问题是在viewDidLoad方法之前不知道真正的内容大小。我们可以采取漫长而错误的道路,并根据字体大小,换行符等计算它。但我们需要强大的解决方案,所以我们将做:

<5233>

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

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

最后要做的是告诉超类updateConstraints

1
[super updateConstraints];

现在我们的班级看起来像:

ResizableTextView.m

1
2
3
4
5
6
7
8
9
10
11
12
- (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平滑地伸展。这是一个例子:

1
2
3
4
5
6
7
8
    [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];

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

编辑:sizeThatFits返回大小但实际上并未调整组件大小。我不确定这是否是您想要的,或者[textView sizeToFit]是否更符合您的要求。在任何一种情况下,我都不知道它是否完全适合您想要的内容,但这是首先尝试的。


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

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

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

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


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

1
2
3
4
5
6
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;这会在文本下方添加一个空白行,如果文本视图正下方有视觉上较重的控件,则可能看起来更好。


我们可以通过约束来实现。

  • 设置UITextView的高度约束。
    enter image description here
  • 2.为该高度约束创建IBOutlet。

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

    3.不要忘记为你的textview设置委托。

    4。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    -(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;
        }];

    }

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


    以下内容就足够了:

  • 只需记住为UITextView设置滚动启用为NO:
  • enter image description here

  • 正确设置自动布局约束。
  • 你甚至可以使用UITableViewAutomaticDimension


    从iOS 8开始,可以使用UITableView的自动布局功能自动调整UITextView的大小,而根本不需要自定义代码。我已经在github上放了一个项目来演示这个,但是关键是:

  • UITextView必须禁用滚动,您可以通过编程方式或通过界面构建??器执行此操作。如果启用滚动,则不会调整大小,因为滚动可让您查看更大的内容。
  • 在UITableViewController的viewDidLoad中,必须为estimatedRowHeight设置一个值,然后将rowHeight设置为UITableViewAutomaticDimension
  • 1
    2
    3
    4
    5
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.tableView.estimatedRowHeight = self.tableView.rowHeight;
        self.tableView.rowHeight = UITableViewAutomaticDimension;
    }
  • 项目部署目标必须是iOS 8或更高版本。

  • 使用自动布局和你的sizetofit的人不起作用,请检查你的宽度约束一次。如果您错过了宽度约束,那么高度将是准确的。

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

    1
    [_textView sizeToFit];

    在这里,我只关心高度,保持宽度固定,并错过了我的TextView在故事板中的宽度约束。

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

    希望这可能有所帮助..


    结合Mike McMaster的回答,您可能希望做以下事情:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [myTextView setDelegate: self];

    ...

    - (void)textViewDidChange:(UITextView *)textView {
      if (myTextView == textView) {
         // it changed.  Do resizing here.
      }
    }

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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];

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // The text must already be added to the subview, or contentviewsize will be wrong.

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

        while (tv.contentSize.height > tv.frame.size.height && pointSize > 7.0) {
            pointSize -= 1.0;
            UIFont *newFont = [UIFont fontWithName:font.fontName size:pointSize];
            tv.font = newFont;
        }
        if (pointSize != font.pointSize)
            NSLog(@"font down to %.1f from %.1f", pointSize, tv.font.pointSize);
    }

    这是@jhibberd的快速版本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        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


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

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

    1
    textView.isScrollEnabled = false

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

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

    输出:

    enter image description here

    enter image description here


    禁用滚动

    >
</p>
<p>
添加constaints
</p>
<p>
<img src=

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

    如果您使用UIScrollView,您也应该添加它;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [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;
    }

    对于iOS 7.0,不要将frame.size.height设置为contentSize.height(当前什么也不做),而是使用[textView sizeToFit]

    看到这个问题。


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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;

    那就是......干杯


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

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

    或者你可以使用

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


    希望这可以帮助:

    1
    2
    3
    4
    5
    - (void)textViewDidChange:(UITextView *)textView {
      CGSize textSize = textview.contentSize;
      if (textSize != textView.frame.size)
          textView.frame.size = textSize;
    }

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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);
    }

    唯一可行的代码是使用'SizeToFit'的代码,如上面的jhibberd答案,但实际上除非你在ViewDidAppear中调用它或将其连接到UITextView文本更改事件,否则它将无法获取。


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        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
                }
            }
        }

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
                    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


    如果您需要在staticTableView中动态调整textViewtableViewCell,这就是答案

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


    就像ios 11上的魅力一样
    我正在一个小区工作,就像一个带泡泡的聊天室。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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)

    这种方法似乎适用于ios7

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     // 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:@"
    "])
        {
            [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;
    }
    }

    Key Value Observing(KVO)非常简单,只需创建UITextView的子类即可:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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
    }

    如果您不想继承子类,可以尝试在contentSize观察器中执行textView.bounds = textView.contentSize


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


    如果您使用的是scrollview和内容视图,并且希望根据TextView内容高度增加高度,那么这段代码将对您有所帮助。

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

    当然设置textview.scrollEnabled = NO;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    -(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 --;gt; 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);
    }

    这是步骤

    解决方案适用于所有版本的iOS。 Swift 3.0及以上版本。

  • UITextView添加到View。我正在添加代码,您可以通过界面构建??器添加。
  • 添加约束。我在代码中添加约束,您也可以在界面生成器中执行此操作。
  • 使用UITextViewDelegate方法func textViewDidChange(_ textView: UITextView)调整TextView的大小
  • 代码:

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    //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
        }
    }
    }

  • 不确定为什么人们总是过于复杂化:
    这里是 :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    - (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];
    }

    推荐阅读

      linux中分命令大小写?

      linux中分命令大小写?,系统,工作,地址,大小写,命令,目录,管理,名称,信息,文

      linux命令查找内容?

      linux命令查找内容?,命令,文件,网络,名称,信息,工作,标准,系统,管理,位置,lin

      linux命令显示内容?

      linux命令显示内容?,标准,系统,数据,命令,百度,实时,时间,信息,文件,内容,lin

      linux命令行字体大小?

      linux命令行字体大小?,系统,等级,图片,数字,工具,终端,字体,字符,图形界面,

      linux创建内容的命令?

      linux创建内容的命令?,名字,文件,命令,密码,时间,系统,文件名,终端,目录,文

      linux下内存调整命令?

      linux下内存调整命令?,系统,情况,地址,工具,总量,总额,管理,内存,机制,内核,

      linux命令增加内容?

      linux命令增加内容?,命令,内容,文件,末尾,编辑,终端,模式,后边,包围,文本,Lin

      linux内存大小命令?

      linux内存大小命令?,系统,情况,电脑,信息,工具,状态,命令,内存,环境,分析,Lin

      linux写入内容命令行?

      linux写入内容命令行?,系统,文件,地方,代码,软件,名字,命令,内容,目录,文本

      linux命令按大小排序?

      linux命令按大小排序?,数字,地址,时间,工作,标准,系统,命令,信息,单位,软件,l

      linux命令显示总大小?

      linux命令显示总大小?,系统,情况,信息,命令,单位,服务,第一,档案,大小,文件

      linux查看命令大小?

      linux查看命令大小?,系统,档案,情况,大小,命令,名称,电脑,单位,地址,时间,lin

      linux命令行调整光标?

      linux命令行调整光标?,标的,位置,系统,设备,光标,状态,第三,流程,软件,通用,l

      linux读文件内容命令?

      linux读文件内容命令?,系统,工作,信息,地址,命令,情况,文件,目录,内容,操作,L

      linux命令常用文字?

      linux命令常用文字?,地址,工作,管理,系统,命令,标准,目录,时间,网络,工具,lin

      linux命令空间大小?

      linux命令空间大小?,系统,信息,情况,单位,命令,设备,公司,地址,大小,空间,如

      linux命令内容追加?

      linux命令内容追加?,系统,管理,命令,统一,工作,简介,文件,内容,操作,用户,Lin

      linux删除文字命令?

      linux删除文字命令?,软件,位置,设备,标的,状态,情况,文件,命令,信息,第一,Lin

      linux命令内容分段?

      linux命令内容分段?,工具,地址,单位,系统,工作,信息,标准,技术,命令,目录,Lin