Подтвердить что ты не робот

Как использовать UIWebView в ячейке таблицы?

Я создаю таблицу с текстом, который является HTML, поэтому я использую UIWebView в качестве подзаголовка своих пользовательских ячеек таблицы. Я уже столкнулся с одной проблемой - при прокрутке вниз в таблице потребуется обновить UIWebViews. Например, я бы просмотрел ячейки в строках с номерами 1, 2 и 3. Я прокрутил вниз, чтобы сказать 8, 9 и 10. На мгновение содержимое UIWebView, которое было видно в ячейке № 8, было содержимое из ячейки # 1, содержимое в ячейке 9 было тем, что из ячейки # 2 и так далее.

Я узнал, что проблема в том, что UIWebViews просто отображают текст медленно. Было предложено вместо этого предварительно загрузить содержимое в UIWebView, как только я смогу, а не ждать, пока таблица не получит cellForRowAtIndexPath. Итак, теперь у меня есть объект домена, который раньше имел только текстовое содержимое WebView, но теперь он фактически имеет ссылку на сам UIWebView.

Но теперь часть содержимого в UIWebView отображает, и когда я просматриваю таблицу, UIWebView показывает только как серый квадрат. Если я коснусь серого окна, он фактически получит прикосновение и обновит WebView - например, если я коснусь ссылки (которую я могу или не могу делать, так как ящик серый, и это будет удачей) связанная с ней страница будет запрошена и отображена правильно.

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {
            // I suppose this isn't necessary since I am just getting it from the
            // Domain Object anyway
    content = [[UIWebView alloc] initWithFrame:CGRectZero];
    content.backgroundColor = [UIColor blackColor];
    [self addSubview:content];
    [content release];
}
return self;
}

// called by cellForRowAtIndexPath 
- (void)setMyDomainObject:(MyDomainObject*)anObject {
UIWebView *contentWebView = anObject.contentWebView;
int contentIndex = [self.subviews indexOfObject:content];
[self insertSubview:contentWebView atIndex:contentIndex];
}
4b9b3361

Ответ 1

Один из способов борьбы с этим - использовать несколько UILabels, каждый с разными шрифтами. Затем стратегически поместите их в ячейку, чтобы сделать их похожими на непрерывный текст. Я видел это в UITableView с очень хорошими результатами.

Другая проблема с производительностью может заключаться в том, что вы переопределяете UItableViewCell и его метод init. Это почти всегда приводит к низкой производительности в UITableView. Вместо этого просто используйте обычные экземпляры UITableViewCell и добавьте в него subviews contentView.

Это широко освещено Matt Gallagher Легкий пользовательский рисунок UITableView.

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

То, что вы сейчас пытаетесь сделать, не может быть выполнено с помощью UIWebview.

Предварительная загрузка не поможет: это замедлит работу пользовательского интерфейса при просмотре изображений в режиме UIWeb за кадром; вы всегда должны практиковать ленивую загрузку на iPhone.

Включение UIWebviews в UITableView будет иметь потенциально неприемлемое поражение производительности. Вам нужно будет использовать другие средства для достижения своей цели.

К сожалению, NSAttributedString недоступен в UIKit, что может легко решить вашу проблему.

Ответ 2

Итак, мой обновленный ответ: я внедрил таблицу, используя один большой UIWebView, чтобы нанести стилизованный текст внутри ячеек таблицы в мое собственное клиентское приложение Twitter, HelTweetica (при наличии источника). Он работает очень хорошо, пока вы понимаете, как делать макет в HTML и CSS.

Вы просто создаете NSMutableString и добавляете строки HTML, которые составляют ваш документ. Вы можете ссылаться на внешние файлы, такие как файлы CSS, которые находятся в изолированной программной среде приложения. Вы можете настроить пользовательские URL-действия, такие как "youraction://file.txt", которые делегат веб-представления может перехватывать и обрабатывать в качестве замены IBAction s:

- (void) refreshWebView {
    TwitterAccount *account = [twitter currentAccount];
    NSMutableString *html = [[NSMutableString alloc] init];
    // Open html and head tags
    [html appendString:@"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"];
    [html appendString:@"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"];
    [html appendString:@"<head>\n"];
    [html appendString:@"<meta name='viewport' content='width=device-width' />"];
    [html appendString:@"<link href='style-ipad.css' rel='styleSheet' type='text/css' />"];
    [html appendString:@"<script language='JavaScript' src='functions.js'></script>"];

    // Body
    [html appendString:@"</head><body><div class='artboard'>"];

    // [...]

    // Close artboard div, body. and html tags
    [html appendString:@"</div></body></html>\n"];

    NSURL *baseURL = [NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]];
    [self.webView loadHTMLString:html baseURL:baseURL];
    [html release];
}

И вы можете перезагрузить части страницы, используя javascript:

- (void) refreshTabArea {
    NSString *html = [self stringByEscapingQuotes: [self tabAreaHTML]];
    NSString *js = [NSString stringWithFormat: @"document.getElementById(\"tab_area\").innerHTML = \"%@\";", html];
    [self.webView stringByEvaluatingJavaScriptFromString:js];
}

Ответ 3

Если содержимое веб-представления ограничено стилизованным текстом или гиперссылками, вы можете взглянуть на проект Three20: http://github.com/joehewitt/three20/tree/master

Его класс TTStyledText поддерживает теги <b>, <i>, <img>, and <a> в контенте. Вероятно, более легкий, чем веб-просмотр.

Ответ 4

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

Ответ 5

Вы сказали: "Вызывается setRowAtIndexPath", вы можете иметь в виду "cellForRowAtIndexPath", который является методом UITableView, вызываемым, когда строка становится видимой и ей необходимо создать ячейку. Убедитесь, что в этом методе вы правильно инициализируете и обновляете содержимое ячеек.

Ответ 6

Вы рассмотрели переопределение метода -prepareForReuse в подклассе ячейки таблицы? Если ячейки не обновляются при прокрутке, возможно, что содержимое повторно используемых ячеек не очищается и reset.

Ответ 7

Я понимаю, что WebView не будет отображаться, если вы не инициируете его загрузку ПОСЛЕ просмотра viewDidLoad().