2016-12-22 3 views
1

Что я пытаюсь сделать, это загрузить некоторые файлы ресурсов HTML в ячейки UITableView. Я хотел бы настроить высоту ячеек в зависимости от размера содержимого UIWebView. Ниже приведены некоторые из моих тестовых кодов.Динамическая высота UITableViewCell для ячейки, которая содержит UIWebView в iOS

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *cellIdentifier = @"TableCellID"; 

    CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 

    if (cell == nil) { 
     NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"CustomTableViewCell" owner:self options:nil]; 
     cell = [nibArray objectAtIndex:0]; 
    } 

    NSString *htmlFileName = [NSString stringWithFormat:@"page%ld", (long)indexPath.row]; 

    NSString *htmlFile = [[NSBundle mainBundle] pathForResource:htmlFileName ofType:@"html"]; 
    NSString *htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil]; 
    [cell.webView loadHTMLString:htmlString baseURL: [[NSBundle mainBundle] bundleURL]]; 

    return cell; 
} 

Если я описываю свою CustomTableViewCell.xib, он имеет UIWebView внутри Content View и UIWebView имеет следующие ограничения данные.

ContentView.Bottom = WebView.Bottom + 8 
ContentView.Top = WebView.Top +8 
ContentView.Leading = WebView.Leading + 8 
ContentView.Trailing = WebView.Trailing + 8 

HTML fils не содержит JavaScript или CSS-контента. Простой, как показано ниже.

<html> 
    <header> 
    </header> 
    <body> 
     <p>eeeee eeeee eeeee eeeee eeeee eeeee eeeee eeeee eeeee eeeee</p> 
    </body> 
</html> 

Теперь мой внешний стаж, как показано ниже.

enter image description here

Как я уже объяснял сверху, мои веб-страница не содержит JavaScript. Поэтому я могу не использовать метод stringByEvaluatingJavaScriptFromString для возврата текста.

+0

Возможный дубликат [Как изменить высоту загруженной ячейки таблицы?] (Http://stackoverflow.com/questions/20666405/how-do-i-change-the-height-of-of- a-table-cell-that-has-already-loaded) –

+0

Я считаю, что вычисление высоты веб-просмотра после его загрузки будет проще, а затем позволит настроить ячейку на основе высоты webView. – Joshua

ответ

0

Я придумал свое решение. Но спасибо всем остальным, кто прокомментировал этот вопрос и открыл мой разум по-разному. Итак, вот что я сделал.

Сначала добавили UIWebViewDelegate в мой класс ViewController

@interface ViewController() <UITableViewDataSource, UITableViewDelegate, UIWebViewDelegate> { 

Затем загрузки HTML-страниц и добавление делегата осуществляется в следующем методе

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *cellIdentifier = @"TableCellID"; 

    CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 

    if (cell == nil) { 

     NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"CustomTableViewCell" owner:self options:nil]; 
     cell = [nibArray objectAtIndex:0]; 
    } 

    cell.webView.delegate = self; 
    cell.webView.tag = indexPath.row; 
    cell.webView.scrollView.scrollEnabled = NO; 

    NSString *htmlFileName = [NSString stringWithFormat:@"page%ld", (long)indexPath.row]; 

    NSString *htmlFile = [[NSBundle mainBundle] pathForResource:htmlFileName ofType:@"html"]; 
    NSString *htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil]; 
    [cell.webView loadHTMLString:htmlString baseURL: [[NSBundle mainBundle] bundleURL]]; 

    return cell; 
} 

После веб-просмотра загружен, рассчитать размер, который подходит для это содержимое и после загрузки всех веб-представлений я перезагружаю данные таблицы, как показано ниже.

- (void)webViewDidFinishLoad:(UIWebView *)webView { 

    if (webView.tag == 0) { 
     [cellHeightMutArray removeAllObjects]; 
    } 

    CGSize fittingSize = [webView sizeThatFits:CGSizeZero]; 

    [cellHeightMutArray insertObject:@(fittingSize.height) atIndex:webView.tag]; 

    if (((webView.tag + 1) == dataArray.count) && !reloadedTableViewAfterLoadingWebContent) { 

     reloadedTableViewAfterLoadingWebContent = YES; 
     _tableView.hidden = NO; 

     [_tableView reloadData]; 
    } 
} 

Тогда я регулирую высоту ячейки (который был основной вопрос, который у меня был)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (cellHeightMutArray.count > 0) { 

     return [[cellHeightMutArray objectAtIndex:indexPath.row] intValue]; 
    } 

    return 44; 
} 

Это мое решение, и он прекрасно работает в iPhone'ов и IPADS.

Но у меня была другая проблема, когда я запускал ее с более сложным пользовательским интерфейсом в iPads, который находится в моем реальном проекте. Я обновлю это, если мои решения по этой проблеме связаны с этим вопросом.

2

Попробуйте

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    arrOfHTMLList= [[NSMutableArray alloc] init]; 
    NSMutableDictionary *dic1 = [[NSMutableDictionary alloc] init]; 
    [dic1 setObject:@"0" forKey:@"height"]; 
    [dic1 setObject:@"aaaaaaaaaa aaaaaa aaaaaaa aaaaaaa aaaaaa aaaaaa aaaaaaaa aaaaa" forKey:@"htmlString"]; 

    NSMutableDictionary *dic2 = [[NSMutableDictionary alloc] init]; 
    [dic1 setObject:@"0" forKey:@"height"]; 
    [dic1 setObject:@"abababababbabababababab ababab bababa ababababb" forKey:@"htmlString"]; 

    NSMutableDictionary *dic3 = [[NSMutableDictionary alloc] init]; 
    [dic1 setObject:@"0" forKey:@"height"]; 
    [dic1 setObject:@"sdajdkjas dkasjkhd jkashjkd sakjhdkj askjdaksh dksajkdkjsah djkasjkhd kjsahjkd asjkhdk jasjkdhaskj" forKey:@"htmlString"]; 

    NSMutableDictionary *dic4 = [[NSMutableDictionary alloc] init]; 
    [dic1 setObject:@"0" forKey:@"height"]; 
    [dic1 setObject:@"sdajdkjas dkasjkhd jkashjkd sakjhdkj askjdaksh dksajkdkjsah djkasjkhd kjsahjkd asjkhdk jasjkdhaskj" forKey:@"htmlString"]; 

    [arrOfHTMLList addObject:dic1]; 
    [arrOfHTMLList addObject:dic2]; 
    [arrOfHTMLList addObject:dic3]; 
    [arrOfHTMLList addObject:dic4]; 
    } 


-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 
    UIWebView *webView = (UIWebView*)[cell viewWithTag:1]; 
    NSString *myHTML = arrOfHTMLList[indexPath.section][@"htmlString"]; 
    [webView loadHTMLString:myHTML baseURL:nil]; 
    webView.delegate = self; 
    webView.frame = CGRectMake(0, 0, screenWidth,cell.frame.size.height); 
return cell; 
} 


-(void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    for (UIView *parent=[webView superview];parent!=nil ;parent=[parent superview]) 
    { 
     if([parent isKindOfClass:[UITableViewCell class]]) 
     { 
      UITableViewCell *cell=(UITableViewCell *)parent; 
      NSIndexPath *indexPath=[_tableView indexPathForCell:cell]; 
      int height = webView.scrollView.contentSize.height; 
      [[arrOfHTMLList objectAtIndex:indexPath.section] setObject:[NSString stringWithFormat:@"%d",height] forKey:@"height"]; 
      [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; 
     } 
    } 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    CGFloat height = [arrOfHTMLList[indexPath.section][@"height"] intValue]; 
    return height; 
} 

Надеется, что это помогает.

+0

это не работает, потому что кадр веб-представления сразу не адаптируется к его содержимому html :) - только async –

+0

также вы забыли вручную вызвать sizeToFit –

+0

@ Daij-Djan, это должно работать, потому что оно вызывает «webView.scrollView.contentSize.height» вместо высоты фрейма. –

0

Основная проблема заключается в том, чтобы получить рамку веб-представления, чтобы сразу адаптироваться к ее содержимому html :) и ТО ТОГО, что после нее асинхронно загружался контент!

- (void)webViewDidFinishLoad:(UIWebView *)aWebView { 
    //TODO: update the table's height for the cell for the webview 
} 

капля в решение, которое я написал обычай UITableViewCell подкласса, который имеет WebView и информирует делегата перезагрузить таблицу:

https://github.com/Daij-Djan/DDUtils/tree/master/objC/DDUtils-IOS/ui/M42WebviewTableViewCell%20%5Bios%5D

самый важный кусок кода:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    M42WebviewTableViewCell *cell = _loadedCells[@(indexPath.row)]; 
    if (!cell) { 
     cell = [[M42WebviewTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; 

     NSString *object = _objects[indexPath.row]; 
     cell.tag = indexPath.row; 
     cell.delegate = self; 
     [cell setHtml:object AndBaseURL:nil]; 
    } 
    return cell; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    //if a cell isnt ready, it wont be there and the method will return 0 
    M42WebviewTableViewCell *cell = _loadedCells[@(indexPath.row)]; 
    return cell.height; 
} 

#pragma mark - M42WebviewTableViewCellDelegate 

- (void)tableCellDidLoadContent:(M42WebviewTableViewCell *)cell { 
    if (!_loadedCells) { 
     _loadedCells = [[NSMutableDictionary alloc] init]; 
    } 
    [_loadedCells setObject:cell forKey:@(cell.tag)]; 

    //only refresh sizes of rows 
    [self.tableView beginUpdates]; 
    [self.tableView endUpdates]; 
} 
Смежные вопросы