I have a UITableview
with multiple reusable TableViewCells. In one cell I have a UITextView
, that resizes itself to fit its content. Now I "just" have to resize the contentView
of the TableViewCell, so I can read the while text. I already tried:
我有一个带有多个可重用的tableviewcell的UITableview。在一个单元格中,我有一个UITextView,它调整自身大小以适应其内容。现在我只需要调整TableViewCell的contentView,这样我就可以读取文本了。我已经尝试:
cell2.contentView.bounds.size.height = cell2.discriptionTextView.bounds.size.height;
Or:
或者:
cell2.contentView.frame = CGRectMake(0, cell2.discriptionTextView.bounds.origin.y,
cell2.discriptionTextView.bounds.size.width,
cell2.discriptionTextView.bounds.size.height);
In the method:
的方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {}
But it won't work.
但它不会工作。
Does anyone know how to do this?
有人知道怎么做吗?
New code:
新代码:
@implementation AppDetail
CGFloat height;
…
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{…
cell2.TextView.text = self.text;
[cell2.TextView sizeToFit];
height = CGRectGetHeight(cell2.TextView.bounds);
…
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
return 143;
}
if (indexPath.row == 1) {
return height;
}
return 0;
}
8 个解决方案
#1
7
You need you implement heightForRowAtIndexPath
.
需要实现heightForRowAtIndexPath。
Say that the data that is to be displayed in the textView is stored in a NSArray.
假设要在textView中显示的数据存储在NSArray中。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat cellheight = 30; //assuming that your TextView's origin.y is 30 and TextView is the last UI element in your cell
NSString *text = (NSString *)[textArray objectAtIndex:indexpath.row];
UIFont *font = [UIFont systemFontOfSize:14];// The font should be the same as that of your textView
CGSize constraintSize = CGSizeMake(maxWidth, CGFLOAT_MAX);// maxWidth = max width for the textView
CGSize size = [text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
cellHeight += size.height; //you can also add a cell padding if you want some space below textView
}
#2
17
You can only resize a UITableViewCell in tableView:heightForRowAtIndexPath:
delegate method.
只能在tableView:heightForRowAtIndexPath:委托方法中调整UITableViewCell的大小。
You have to estimate what the size of the text will be when that method is called for every row when the tableView is loaded.
您必须估计当加载tableView时为每一行调用该方法时文本的大小。
This is what I did to solve the problem.
这就是我解决问题的方法。
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * yourText = self.myArrayWithTextInIt[indexPath.row]; // or however you are getting the text
return additionalSpaceNeeded + [self heightForText:yourText];
}
-(CGFloat)heightForText:(NSString *)text
{
NSInteger MAX_HEIGHT = 2000;
UITextView * textView = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, WIDTH_OF_TEXTVIEW, MAX_HEIGHT)];
textView.text = text;
textView.font = // your font
[textView sizeToFit];
return textView.frame.size.height;
}
EDIT
编辑
While I used this solution for a while, I found a more optimal one that I would recommend using as it doesn't require allocating an entire textView in order to work, and can handle text greater than 2000.
当我使用这个解决方案的时候,我发现了一个更理想的方法,我建议使用它,因为它不需要分配整个textView来工作,并且可以处理大于2000的文本。
-(CGFloat)heightForTextViewRectWithWidth:(CGFloat)width andText:(NSString *)text
{
UIFont * font = [UIFont systemFontOfSize:12.0f];
// this returns us the size of the text for a rect but assumes 0, 0 origin
CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
// so we calculate the area
CGFloat area = size.height * size.width;
CGFloat buffer = whateverExtraBufferYouNeed.0f;
// and then return the new height which is the area divided by the width
// Basically area = h * w
// area / width = h
// for w we use the width of the actual text view
return floor(area/width) + buffer;
}
#3
14
As @Rob Norback said, There is something called UITableViewAutomaticDimension
.
正如@Rob Norback所说,有一种叫做UITableViewAutomaticDimension的东西。
For Swift, The easiest way to resize content from UITableViewCell on the fly is to just add this.
对于Swift来说,从UITableViewCell中调整内容的最简单方法就是添加这个。
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
#4
12
Here's an updated version for iOS 7+ that is cleaner (no extra method)
这是iOS 7+的更新版本,更简洁(没有额外的方法)
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIFont * font = [UIFont systemFontOfSize:15.0f];
NSString *text = [getYourTextArray objectAtIndex:indexPath.row];
CGFloat height = [text boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width, maxHeight) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName: font} context:nil].size.height;
return height + additionalHeightBuffer;
}
#5
2
This thread has been quite a while, but in iOS 8 UITableViewAutomaticDimension
was introduced. You have to set constraints from the top to the bottom of the cell like a scroll view to make this work. But after that, just add the following code to viewDidLoad()
:
这个线程已经有很长一段时间了,但是在ios8 UITableViewAutomaticDimension中引入了。您必须从单元格的顶部到底部设置约束,就像滚动视图一样。但在此之后,只需将以下代码添加到viewDidLoad():
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 122.0
Make sure your estimated height is as close as possible to the real thing otherwise you'll get some buggy scrolling.
确保你估计的高度尽可能接近真实的东西,否则你会得到一些错误的滚动。
#6
1
I favor this solution of Jure
我喜欢用Jure溶液
- First, set constraints of textview to be pinned with its superview (cell's contentView in this case).
- 首先,将textview的约束设置为与其父视图(本例中为单元格的contentView)固定。
- Disable
textView.scrollEnabled
- 禁用textView.scrollEnabled
-
Set
集
table.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = 44;
If finally, your code not works, then use this instead
如果您的代码最终不工作,那么使用这个
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44; }
-
Implement
UITextViewDelegate
like this:实现UITextViewDelegate是这样的:
- (void)textViewDidChange:(UITextView *)textView { CGPoint currentOffset = self.tableView.contentOffset; [UIView setAnimationsEnabled:NO]; [self.tableView beginUpdates]; [self.tableView endUpdates]; [UIView setAnimationsEnabled:YES]; [self.tableView setContentOffset:currentOffset animated:NO]; }
#7
1
Adding these two methods to the ViewController with UITableViewAutomaticDimension should do the trick. It has worked for me when embedding a UITextView inside of a UITableViewCell with variable length text.
使用UITableViewAutomaticDimension将这两个方法添加到视图控制器中应该可以达到这个目的。在UITableViewCell中嵌入可变长度的文本时,它对我很有用。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
#8
0
In case of UILabel subview in the UITableViewCell, I accomplished auto resize of the label just by setting the label's constraints (using storyboard, Xcode 8.3.2).
在UITableViewCell中的UILabel子视图中,我通过设置标签的约束(使用storyboard, Xcode 8.3.2)实现了标签的自动调整大小。
This is working since apparently the label's and the cell's default behavior is sizeToFit. Same should work for UITextView as well.
这是有效的,因为标签和单元格的默认行为是sizeToFit。UITextView也应该是这样。
#1
7
You need you implement heightForRowAtIndexPath
.
需要实现heightForRowAtIndexPath。
Say that the data that is to be displayed in the textView is stored in a NSArray.
假设要在textView中显示的数据存储在NSArray中。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat cellheight = 30; //assuming that your TextView's origin.y is 30 and TextView is the last UI element in your cell
NSString *text = (NSString *)[textArray objectAtIndex:indexpath.row];
UIFont *font = [UIFont systemFontOfSize:14];// The font should be the same as that of your textView
CGSize constraintSize = CGSizeMake(maxWidth, CGFLOAT_MAX);// maxWidth = max width for the textView
CGSize size = [text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
cellHeight += size.height; //you can also add a cell padding if you want some space below textView
}
#2
17
You can only resize a UITableViewCell in tableView:heightForRowAtIndexPath:
delegate method.
只能在tableView:heightForRowAtIndexPath:委托方法中调整UITableViewCell的大小。
You have to estimate what the size of the text will be when that method is called for every row when the tableView is loaded.
您必须估计当加载tableView时为每一行调用该方法时文本的大小。
This is what I did to solve the problem.
这就是我解决问题的方法。
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * yourText = self.myArrayWithTextInIt[indexPath.row]; // or however you are getting the text
return additionalSpaceNeeded + [self heightForText:yourText];
}
-(CGFloat)heightForText:(NSString *)text
{
NSInteger MAX_HEIGHT = 2000;
UITextView * textView = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, WIDTH_OF_TEXTVIEW, MAX_HEIGHT)];
textView.text = text;
textView.font = // your font
[textView sizeToFit];
return textView.frame.size.height;
}
EDIT
编辑
While I used this solution for a while, I found a more optimal one that I would recommend using as it doesn't require allocating an entire textView in order to work, and can handle text greater than 2000.
当我使用这个解决方案的时候,我发现了一个更理想的方法,我建议使用它,因为它不需要分配整个textView来工作,并且可以处理大于2000的文本。
-(CGFloat)heightForTextViewRectWithWidth:(CGFloat)width andText:(NSString *)text
{
UIFont * font = [UIFont systemFontOfSize:12.0f];
// this returns us the size of the text for a rect but assumes 0, 0 origin
CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
// so we calculate the area
CGFloat area = size.height * size.width;
CGFloat buffer = whateverExtraBufferYouNeed.0f;
// and then return the new height which is the area divided by the width
// Basically area = h * w
// area / width = h
// for w we use the width of the actual text view
return floor(area/width) + buffer;
}
#3
14
As @Rob Norback said, There is something called UITableViewAutomaticDimension
.
正如@Rob Norback所说,有一种叫做UITableViewAutomaticDimension的东西。
For Swift, The easiest way to resize content from UITableViewCell on the fly is to just add this.
对于Swift来说,从UITableViewCell中调整内容的最简单方法就是添加这个。
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
#4
12
Here's an updated version for iOS 7+ that is cleaner (no extra method)
这是iOS 7+的更新版本,更简洁(没有额外的方法)
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIFont * font = [UIFont systemFontOfSize:15.0f];
NSString *text = [getYourTextArray objectAtIndex:indexPath.row];
CGFloat height = [text boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width, maxHeight) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName: font} context:nil].size.height;
return height + additionalHeightBuffer;
}
#5
2
This thread has been quite a while, but in iOS 8 UITableViewAutomaticDimension
was introduced. You have to set constraints from the top to the bottom of the cell like a scroll view to make this work. But after that, just add the following code to viewDidLoad()
:
这个线程已经有很长一段时间了,但是在ios8 UITableViewAutomaticDimension中引入了。您必须从单元格的顶部到底部设置约束,就像滚动视图一样。但在此之后,只需将以下代码添加到viewDidLoad():
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 122.0
Make sure your estimated height is as close as possible to the real thing otherwise you'll get some buggy scrolling.
确保你估计的高度尽可能接近真实的东西,否则你会得到一些错误的滚动。
#6
1
I favor this solution of Jure
我喜欢用Jure溶液
- First, set constraints of textview to be pinned with its superview (cell's contentView in this case).
- 首先,将textview的约束设置为与其父视图(本例中为单元格的contentView)固定。
- Disable
textView.scrollEnabled
- 禁用textView.scrollEnabled
-
Set
集
table.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = 44;
If finally, your code not works, then use this instead
如果您的代码最终不工作,那么使用这个
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44; }
-
Implement
UITextViewDelegate
like this:实现UITextViewDelegate是这样的:
- (void)textViewDidChange:(UITextView *)textView { CGPoint currentOffset = self.tableView.contentOffset; [UIView setAnimationsEnabled:NO]; [self.tableView beginUpdates]; [self.tableView endUpdates]; [UIView setAnimationsEnabled:YES]; [self.tableView setContentOffset:currentOffset animated:NO]; }
#7
1
Adding these two methods to the ViewController with UITableViewAutomaticDimension should do the trick. It has worked for me when embedding a UITextView inside of a UITableViewCell with variable length text.
使用UITableViewAutomaticDimension将这两个方法添加到视图控制器中应该可以达到这个目的。在UITableViewCell中嵌入可变长度的文本时,它对我很有用。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
#8
0
In case of UILabel subview in the UITableViewCell, I accomplished auto resize of the label just by setting the label's constraints (using storyboard, Xcode 8.3.2).
在UITableViewCell中的UILabel子视图中,我通过设置标签的约束(使用storyboard, Xcode 8.3.2)实现了标签的自动调整大小。
This is working since apparently the label's and the cell's default behavior is sizeToFit. Same should work for UITextView as well.
这是有效的,因为标签和单元格的默认行为是sizeToFit。UITextView也应该是这样。