首页 / 知识

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

2023-04-14 14:38:00

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];
    }

    调整文字大小很好

    最新内容

    相关内容

    猜你喜欢