我有一个UITableView
,其中填充了自定义单元格(继承自UITableViewCell
),每个单元格都包含一个UIWebView
,根据其内容自动调整大小。这就是问题,如何根据内容(变量UITableView
)更改webView
单元格的高度。
解决方案必须是动态的,因为用于填充UIWebViews
的HTML是从不断变化的Feed中解析的。
我觉得我需要使用UITableView
委托方法heightForRowAtIndexPath
但是从它的定义:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
;//This needs to be variable
}
我无法访问单元格或其内容。我可以在cellForRowAtIndexPath
?
任何帮助都会很棒。感谢。
我在2年前问过这个问题。通过自动布局的介绍,可以找到iOS7的最佳解决方案:
Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
在iOS8上,此功能内置于SDK
中答案 0 :(得分:24)
这通常效果很好:
目标-C:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
夫特:
override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
return UITableViewAutomaticDimension;
}
答案 1 :(得分:20)
我发现动态高度的最佳方法是预先计算高度并将其存储在某种类型的集合中(可能是数组)。假设单元格主要包含文本,则可以使用-[NSString sizeWithFont:constrainedToSize:lineBreakMode:]
计算高度,然后返回heightForRowAtIndexPath:
如果内容不断变化,您可以实现一种方法,在提供新数据时更新高度数组。
答案 2 :(得分:6)
self.tblVIew.estimatedRowHeight = 500.0; // put max you expect here.
self.tblVIew.rowHeight = UITableViewAutomaticDimension;
答案 3 :(得分:5)
我尝试了很多解决方案,但有一个解决方案就是这个,由朋友建议:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
int height = [StringUtils findHeightForText:yourLabel havingWidth:yourWidth andFont:[UIFont systemFontOfSize:17.0f]];
height += [StringUtils findHeightForText:yourOtherLabel havingWidth:yourWidth andFont:[UIFont systemFontOfSize:14.0f]];
return height + CELL_SIZE_WITHOUT_LABELS; //important to know the size of your custom cell without the height of the variable labels
}
StringUtils.h类:
#import <Foundation/Foundation.h>
@interface StringUtils : NSObject
+ (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font;
@end
StringUtils.m class:
#import "StringUtils.h"
@implementation StringUtils
+ (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font {
CGFloat result = font.pointSize+4;
if (text) {
CGSize size;
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:font}
context:nil];
size = CGSizeMake(frame.size.width, frame.size.height+1);
result = MAX(size.height, result); //At least one row
}
return result;
}
@end
它对我来说很完美。我有一个自定义单元格,其中包含3个固定尺寸的图像,2个固定尺寸的标签和2个可变标签。
答案 4 :(得分:3)
这是我从twitter获取推文然后将它们存储在CoreData中以供离线阅读时用于动态单元格高度的代码。
这不仅展示了如何获取单元格和数据内容,还展示了如何使用填充动态地将UILabel大小调整为内容
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
Tweet *tweet = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString* text = tweet.Text;
TweetTableViewCell *cell = (TweetTableViewCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
//Set the maximum size
CGSize maximumLabelSize = cell.tweetLabel.frame.size;
CGPoint originalLocation = cell.tweetLabel.frame.origin;
//Calculate the new size based on the text
CGSize expectedLabelSize = [text sizeWithFont:cell.tweetLabel.font constrainedToSize:maximumLabelSize lineBreakMode:cell.tweetLabel.lineBreakMode];
//Dynamically figure out the padding for the cell
CGFloat topPadding = cell.tweetLabel.frame.origin.y - cell.frame.origin.y;
CGFloat bottomOfLabel = cell.tweetLabel.frame.origin.y + cell.tweetLabel.frame.size.height;
CGFloat bottomPadding = cell.frame.size.height - bottomOfLabel;
CGFloat padding = topPadding + bottomPadding;
CGFloat topPaddingForImage = cell.profileImage.frame.origin.y - cell.frame.origin.y;
CGFloat minimumHeight = cell.profileImage.frame.size.height + topPaddingForImage + bottomPadding;
//adjust to the new size
cell.tweetLabel.frame = CGRectMake(originalLocation.x, originalLocation.y, cell.tweetLabel.frame.size.width, expectedLabelSize.height);
CGFloat cellHeight = expectedLabelSize.height + padding;
if (cellHeight < minimumHeight) {
cellHeight = minimumHeight;
}
return cellHeight;
}
答案 5 :(得分:3)
我认为这样的算法也适合你:
1)在cellForrowAtIndexPath中激活你的webview进行加载,并为它们提供等于indexPath.row的标签
2)在webViewDidFinishLoading中,您计算单元格中内容的高度,并使用键和值组成一个字典,如下所示:key = indexPath.row value = height
3)调用[tableview reloadData]