Изменение размера высоты UIWebView для соответствия содержимому

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

Этот UITableViewCell также можно сбрасывать, не отображая UIWebView когда он находится в состоянии свертывания.

Руд, как я знаю, что эта высота, чтобы я мог иметь heightForRowAtIndexPath вернуть правильное значение и позволить таблице выглядеть и прокручивать правильно?

Вот пример кода:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0)
    return 286;

if (indexPath.row == 1) {
    if (analysisExpanded)
        return analysisWebViewHeight + 39;
    else 
        return 52;
}

if (sourcesExpanded)
    return sourcesWebViewHeight + 39;

return 53;

}

Довольно просто. 39 - это высота некоторых заголовков, которые у меня есть в ячейке с веб-просмотром.

Я загружаю "расширенный вид" ячейки из наконечника, поэтому, чтобы получить веб-представление, я вызываю viewForTag:

        UIWebView* sourcesWebView = (UIWebView*)[cell viewWithTag:1];
        [sourcesWebView setBackgroundColor:[UIColor clearColor]];
        [sourcesWebView loadHTMLString:placeholder baseURL:[NSURL URLWithString:@"http://example.com/"]];
        sourcesWebViewHeight = [[sourcesWebView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollHeight"] floatValue];
        [sourcesWebView setFrame:CGRectMake(sourcesWebView.frame.origin.x, sourcesWebView.frame.origin.y, sourcesWebView.frame.size.width, sourcesWebViewHeight)];

sourcesWebViewHeight - это iVar, который обновляется приведенным выше кодом в cellForRowAtIndexPath. Если пользователь три раза удаляет ячейку, разворачивает-сворачивает-разворачивает и делает небольшую прокрутку, в конечном итоге получает правильную высоту.

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

Ответ 1

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

После реализации метода делегирования didFinishLoad мой оригинальный javascript отлично работал, чтобы получить высоту.

Ответ 2

Для iOS Safari вам необходимо использовать следующую строку:

NSInteger height = [[sourcesWebView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"] integerValue];

document.documentElement.scrollHeight не работает для этого браузера.

Просто, чтобы быть уверенным, что все правильно, вам нужно вызвать это после того, как ваш веб-просмотр завершил загрузку =)

UPDATE: еще один вариант, который будет работать только для iOS5, они добавили свойство scrollView в UIWebView, где вы можете получить contentSize.

Ответ 3

Поскольку webViewDelegate может получить высоту webView при загрузке HTML-кода, метод tableview:heightForRowAtIndexPath: будет вводить бесконечный цикл для попытки получить webView, расположенный в CellView Cell:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    float height;

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    UIWebView *webContent = (UIWebView *) [cell viewWithTag:tagTableSingleContentWeb];
    CGRect frame = webContent.frame;

    height = frame.origin.y + frame.size.height + 30;

    return height;
}

Вышеупомянутый код я попытался изменить ячейку tableView, когда я вставляю HTML-код в webView внутри ячейки tableView, но это вызовет бесконечный цикл....

Я все еще пытаюсь найти другой путь.

ps WebViewDelegate путь в порядке, когда webView находится в ScrollView, но я не могу заставить его работать внутри ячейки TableView еще.

Ответ 4

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