ios - UITableViewCell with UIWebview that adjusts height to content size -
so pulling html string down api , trying load uiwebview in uitableviewcell , content scrolls in cell. need have webview's height adjust size of content , adjust cell accordingly. found post here in swift: uitableviewcell uiwebview dynamic height , tried doing same thing having trouble because using nsmutablearray store nsnumber float , trying load in cellforrowatindexpath , heightforrowatindexpath both execute before webview delegate method gets called index out of bounds error.
so far have this:
@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
thanks in advance!
the auto layout approach might tricky. easier approach set frame of corresponding cell in webviewdidfinishload
. can use cellforrowatindexpath
on table view displayed cell (it won't try cell uitableviewdatasource
if it's displayed because it'll cached).
- (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); }