Comments 18
1. Вариант с UIWebview очень тяжелый и на старых девайсах (а иначе нет смысла в 3-ей прошивке вообще) он, насколько, я помню тормозит даже на простом контенте.
2. Пользователей 3-ей прошивки меньше 10%.
3. Я за подход с UILabel. Можно сделать форматирование попроще, но безтормозную работу.
2. Пользователей 3-ей прошивки меньше 10%.
3. Я за подход с UILabel. Можно сделать форматирование попроще, но безтормозную работу.
по моему совсем не правильно что либо грузить в cellForRowAtIndexPath. т.е. сначала надо либо все загрузить, либо производить все загрузки асинхронно в объектах data source, в ячейка же просто подписываться на готовность данных и отображать по факту.
речь идет о reusable cells, когда реально объектов UITableViewCell на всю таблицу меньше десятка и контент в конкретную ячейку подставляется именно в cellForRowAtIndexPath
у меня похожая таблица в проекте. просто использую кастомную ячейку и контент отдаю объектом, в котором и происходит загрузка. структура примерно такая
— статичный класс DataLoader отвечающий за загрузку данных, собирает коллекцию из DataObject
— DataObject который берет на себя работу по асинхронной загрузке данных, например изображения, или подготовка html
— TableViewController подписанный на событие загрузки данных и перегружающий таблицу при их поступлении
— CustomTableViewCell принимает DataObject и отображает ячейку в зависимости от состояния, подписываем его на изменения в DataObject
вот и все. Данные отдельно, отображение отдельно. можем в любой момент грузить что угодно не пересекаясь с интерфейсом
— статичный класс DataLoader отвечающий за загрузку данных, собирает коллекцию из DataObject
— DataObject который берет на себя работу по асинхронной загрузке данных, например изображения, или подготовка html
— TableViewController подписанный на событие загрузки данных и перегружающий таблицу при их поступлении
— CustomTableViewCell принимает DataObject и отображает ячейку в зависимости от состояния, подписываем его на изменения в DataObject
вот и все. Данные отдельно, отображение отдельно. можем в любой момент грузить что угодно не пересекаясь с интерфейсом
дело в том что контроллер дергает cellForRowAtIndexPath каждый раз как ячейка попадает в видимую область скролла, соответственно вы повторно грузите контент и описанная проблема как раз из за этого. Конечно можно использовать уникальный identifier для каждой ячейки, но это не уберет проблему при первой инициализации, хреново скажется на производительности если ячеек много
Никак не могу понять ваш point. Какой из описанных вами ваше объектов непосредственно рендерит контент? и какой именно контент?
В моем случае рендером занимается UIWebView внутри UITableViewCell и проблема именно в том что после вызова loadHTMLString реальный рендер начнется ТОЛЬКО после того как decelrating таблицы при скролле завершится, хотя если хтмл достаточно простой, его рендер можно делать синхронно с этим скроллом без ущерба usability. И я показал как это сделать.
В моем случае рендером занимается UIWebView внутри UITableViewCell и проблема именно в том что после вызова loadHTMLString реальный рендер начнется ТОЛЬКО после того как decelrating таблицы при скролле завершится, хотя если хтмл достаточно простой, его рендер можно делать синхронно с этим скроллом без ущерба usability. И я показал как это сделать.
Рендер контента должен делать UITableViewCell, подготовку и загрузку — DataSource.
В вашем случае UIWebView это часть контента, следовательно готовить его надо отдельно от логики отображения ячеек.
В примере вы грузите его каждый раз как ячейка появляется на экране, отсюда задержка
В вашем случае UIWebView это часть контента, следовательно готовить его надо отдельно от логики отображения ячеек.
В примере вы грузите его каждый раз как ячейка появляется на экране, отсюда задержка
Теперь я понял что вы предлагаете reusable cells но не reusable WebViews. Так можно сделать, будет ущерб в памяти, но выигрыш в быстродействии.
Я же выбрал путь reusbale webviews.
Кстати ваш пример с асинхронной загрузкой в DataSource не решит поставленной задачи, так как контент появится все равно не сразу, а только после того как скроллинг таблицы остановится (в силу специфики работы UIWebView), я же хотел чтобы контент появлялся сразу.
Я же выбрал путь reusbale webviews.
Кстати ваш пример с асинхронной загрузкой в DataSource не решит поставленной задачи, так как контент появится все равно не сразу, а только после того как скроллинг таблицы остановится (в силу специфики работы UIWebView), я же хотел чтобы контент появлялся сразу.
Посмотрите на github.com/Cocoanetics/NSAttributedString-Additions-for-HTML, неплохая реализация на базе CoreText.
Это так же можно сделать создав свой подкласс UITextView и вставив в UITableViewCell
Так я решил задачу делая твиттер клиент
AMStyledText.h
AMStyledText.m
И вот как получилось
http://habrastorage.org/storage1/b3c106b3/86e3db51/417b34a6/999457ce.png
Так я решил задачу делая твиттер клиент
AMStyledText.h
#import <UIKit/UIKit.h>
@interface UITextView (extended)
- (void)setContentToHTMLString:(NSString *)contentText;
@end
@class WebView, WebFrame;
@protocol WebPolicyDecisionListener;
@interface AMStyledText : UITextView {
}
AMStyledText.m
#import "AMStyledText.h"
@implementation AMStyledText
- (void)setContentToHTMLString:(NSString *)contentText {
[super setContentToHTMLString:contentText];
}
@end
И вот как получилось
http://habrastorage.org/storage1/b3c106b3/86e3db51/417b34a6/999457ce.png
вариант private API не рассматривался вообще и лично мной не будет рассматриваться никогда.
Тем не менее приложение в AppStore, а private не private согласен, тут подход у каждого свой
сейчас похоже что эпл ужесточяется с private api, последнее мое приложения завернули за простое объявление метода _updateView, хотя он даже не использовался.
Вероятность что вы там останетесь после следующего апдейта крайней мала. Я уже фиксил проект который был в аппстор, но минимальное обновление завернули по причине private api.
Sign up to leave a comment.
Синхронная загрузка UIWebView