带有 UIWebview 的 UITableViewCell,可根据内容大小调整高度
UITableViewCell with UIWebview that adjusts height to content size
所以我从 API 中拉下 HTML 字符串,我试图将它加载到 UITableViewCell 中的 UIWebView 中,并且内容在单元格中滚动。我需要将 webview 的高度调整为内容的大小,然后相应地调整单元格。我在 swift 中找到了一个 post:
我尝试做同样的事情,但我遇到了一些麻烦,因为我使用 NSMutableArray 来存储带有浮点数的 NSNumber,然后尝试加载它,但是 cellForRowAtIndexPath 和 heightForRowAtIndexPath 都在 webview 委托方法被调用之前执行,所以我会得到一个索引越界错误。
到目前为止我有这个:
@interface FGCThreadDetailTableViewController ()
@property (copy, nonatomic) NSArray<FGCThreadModel*>* threads;
@property (copy, nonatomic) NSMutableArray* contentHeights;
@end
@implementation FGCThreadDetailTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[FGCThreadDetailCell class] forCellReuseIdentifier:@"threadDetailCell"];
self.tableView.estimatedRowHeight = 100;
self.tableView.rowHeight = UITableViewAutomaticDimension;
[SVProgressHUD show];
[[FGCThread postsByThreadID:_threadID] subscribeNext:^(id x) {
_threads = x;
[SVProgressHUD dismiss];
[self.tableView reloadData];
}];
_contentHeights = [[NSMutableArray alloc] init];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _threads.count;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FGCThreadDetailCell* cell = [tableView dequeueReusableCellWithIdentifier:@"threadDetailCell" forIndexPath:indexPath];
FGCThreadModel* thread = _threads[indexPath.row];
cell.webView.delegate = self;
CGFloat htmlHeight;
htmlHeight = [_contentHeights[indexPath.row] floatValue];
cell.webView.tag = indexPath.row;
[cell.webView loadHTMLString:thread.postBodyHTMLString baseURL:nil];
cell.webView.frame = CGRectMake(0, 0, cell.frame.size.width, htmlHeight);
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [_contentHeights[indexPath.row] floatValue];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (_contentHeights[webView.tag]) {
return;
}
_contentHeights[webView.tag] = [NSNumber numberWithFloat:[[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"] floatValue]];
[self.tableView reloadData];
}
@end
提前致谢!
自动布局方法可能很棘手。一种更简单的方法是只设置 webViewDidFinishLoad
中相应单元格的框架。您可以在 table 视图上使用 cellForRowAtIndexPath
来获取显示的单元格(如果它已经显示,它不会尝试从 UITableViewDataSource
获取单元格,因为它会被缓存)。
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (_contentHeights[webView.tag]) {
return;
}
float height = [NSNumber numberWithFloat:[[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"] floatValue]];
NSIndexPath* indexOfCell = [NSIndexPath indexPathForRow:webView.tag inSection:0];
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexOfCell];
cell.frame = CGRectMake(0, 0, cell.frame.size.width, height);
}
所以我从 API 中拉下 HTML 字符串,我试图将它加载到 UITableViewCell 中的 UIWebView 中,并且内容在单元格中滚动。我需要将 webview 的高度调整为内容的大小,然后相应地调整单元格。我在 swift 中找到了一个 post:
到目前为止我有这个:
@interface FGCThreadDetailTableViewController ()
@property (copy, nonatomic) NSArray<FGCThreadModel*>* threads;
@property (copy, nonatomic) NSMutableArray* contentHeights;
@end
@implementation FGCThreadDetailTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[FGCThreadDetailCell class] forCellReuseIdentifier:@"threadDetailCell"];
self.tableView.estimatedRowHeight = 100;
self.tableView.rowHeight = UITableViewAutomaticDimension;
[SVProgressHUD show];
[[FGCThread postsByThreadID:_threadID] subscribeNext:^(id x) {
_threads = x;
[SVProgressHUD dismiss];
[self.tableView reloadData];
}];
_contentHeights = [[NSMutableArray alloc] init];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _threads.count;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FGCThreadDetailCell* cell = [tableView dequeueReusableCellWithIdentifier:@"threadDetailCell" forIndexPath:indexPath];
FGCThreadModel* thread = _threads[indexPath.row];
cell.webView.delegate = self;
CGFloat htmlHeight;
htmlHeight = [_contentHeights[indexPath.row] floatValue];
cell.webView.tag = indexPath.row;
[cell.webView loadHTMLString:thread.postBodyHTMLString baseURL:nil];
cell.webView.frame = CGRectMake(0, 0, cell.frame.size.width, htmlHeight);
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [_contentHeights[indexPath.row] floatValue];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (_contentHeights[webView.tag]) {
return;
}
_contentHeights[webView.tag] = [NSNumber numberWithFloat:[[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"] floatValue]];
[self.tableView reloadData];
}
@end
提前致谢!
自动布局方法可能很棘手。一种更简单的方法是只设置 webViewDidFinishLoad
中相应单元格的框架。您可以在 table 视图上使用 cellForRowAtIndexPath
来获取显示的单元格(如果它已经显示,它不会尝试从 UITableViewDataSource
获取单元格,因为它会被缓存)。
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (_contentHeights[webView.tag]) {
return;
}
float height = [NSNumber numberWithFloat:[[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"] floatValue]];
NSIndexPath* indexOfCell = [NSIndexPath indexPathForRow:webView.tag inSection:0];
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexOfCell];
cell.frame = CGRectMake(0, 0, cell.frame.size.width, height);
}