是否有一个好的方法来调整UITextView的大小以符合其内容?例如,我有一个包含一行文本的UITextView:

"Hello world"

然后我添加了另一行文本:

"Goodbye world"

在Cocoa Touch中是否有一个好的方法来获取矩形来保存文本视图中的所有行,这样我就可以相应地调整父视图?

另一个例子是,查看Calendar应用程序中用于事件的notes字段——注意单元格(以及它包含的UITextView)如何展开以保存notes字符串中的所有文本行。


当前回答

禁用滚动

添加constaints

然后添加文本

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

其他回答

这个方法似乎适用于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;
}
}

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

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

以下是步骤

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

添加你的UITextView到View。我用代码添加它,你可以通过界面生成器添加。 添加约束。我在代码中添加约束,你也可以在接口生成器中这样做。 使用UITextViewDelegate方法func textViewDidChange(_ textView: UITextView)来调整textView的大小

代码:

//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 } } }

禁用滚动

添加constaints

然后添加文本

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

不知道为什么人们总是把事情复杂化: 下面就是:

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