Как использовать UIWebView в ячейке таблицы? - PullRequest
16 голосов
/ 15 марта 2009

Я строю таблицу с некоторым текстом, который представляет собой 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];
}

Ответы [ 7 ]

9 голосов
/ 30 мая 2009

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

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

Это было подробно описано в Easy Custom UITableView Drawing Мэтта Галлахера .

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

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

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

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

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

6 голосов
/ 28 апреля 2010

Итак, вот мой обновленный ответ: я реализовал таблицу, используя один большой 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];
}
4 голосов
/ 27 мая 2009

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

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

2 голосов
/ 21 марта 2009

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

1 голос
/ 16 марта 2009

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

0 голосов
/ 27 апреля 2010

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

0 голосов
/ 15 марта 2009

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

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