ios 如何调整 UITableViewCell 的大小以适应其内容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19211083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to resize UITableViewCell to fit its content?
提问by David G?lzh?user
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:
我有UITableview
多个可重用的 TableViewCells。在一个单元格中,我有一个UITextView
,它会调整自身大小以适应其内容。现在我“只需要”调整contentView
TableViewCell 的大小,这样我就可以阅读 while 文本。我已经尝试过:
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;
}
采纳答案by dRAGONAIR
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
}
回答by AdamG
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;
}
回答by r_19
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
}
回答by enc_life
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;
}
回答by samthui7
I favor this solution of Jure
我赞成Jure 的这个解决方案
- First, set constraints of textview to be pinned with its superview (cell's contentView in this case).
- Disable
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:- (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]; }
- 首先,将 textview 的约束设置为其超级视图(在本例中为单元格的 contentView)。
- 禁用
textView.scrollEnabled
放
table.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = 44;
如果最后,您的代码不起作用,请改用它
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44; }
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]; }
回答by Rob Norback
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()
:
这个线程已经有一段时间了,但在 iOS 8 中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.
确保您的估计高度尽可能接近真实高度,否则滚动时会出现一些错误。
回答by Stephen
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 将这两个方法添加到 ViewController 应该可以解决问题。将 UITextView 嵌入具有可变长度文本的 UITableViewCell 时,它对我有用。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
回答by mark
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 子视图,我仅通过设置标签的约束(使用故事板,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。