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

"Hello world"

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

"Goodbye world"

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

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


当前回答

如果你手边没有UITextView(例如,你正在调整表格视图单元格的大小),你将不得不通过测量字符串来计算大小,然后在UITextView的每一侧占用8 pt的填充。例如,如果你知道你的文本视图的期望宽度,并想要计算出相应的高度:

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只是一个非常大的最大尺寸。

实际上,您可能想要添加额外的字体。通向高处;这将在文本下方添加一个空行,如果文本视图正下方有视觉上沉重的控件,这可能会看起来更好。

其他回答

更新

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

myTextView.scrollEnabled = @NO

原来的答案

要在UITableViewCell中创建一个动态大小的UITextView,我发现以下组合在Xcode 6和iOS 8 SDK中有效:

Add a UITextView to a UITableViewCell and constrain it to the sides Set the UITextView's scrollEnabled property to NO. With scrolling enabled, the frame of the UITextView is independent of its content size, but with scrolling disabled, there is a relationship between the two. If your table is using the original default row height of 44 then it will automatically calculate row heights, but if you changed the default row height to something else, you may need to manually switch on auto-calculation of row heights in viewDidLoad: tableView.estimatedRowHeight = 150; tableView.rowHeight = UITableViewAutomaticDimension;

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

实现UITextViewDelegate协议的textViewDidChange:方法,并告诉tableView在每次文本被编辑时重新绘制自己: - (void)textViewDidChange:(UITextView *)textView; { [tableView beginUpdates]; [tableView endUpdates]; } 别忘了在某个地方设置UITextView委托,在Storyboard或者tableView:cellForRowAtIndexPath:

唯一可以工作的代码是使用'SizeToFit'的代码,如上面的jhibberd answer,但实际上它不会拾取,除非你在ViewDidAppear中调用它或将其连接到UITextView text changed event。

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

UITextView必须禁用滚动,这可以通过编程或通过接口构建器来实现。如果启用滚动,它将不会调整大小,因为滚动可以让您查看较大的内容。 在UITableViewController的viewDidLoad中,你必须为estimatedRowHeight设置一个值,然后将rowHeight设置为UITableViewAutomaticDimension。


- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}

项目部署目标必须是iOS 8或更高版本。

以下是步骤

解决方案适用于所有版本的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 } } }

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

-(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)大小

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

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