iphone: ошибка и вопрос о pdf-страницах - PullRequest
0 голосов
/ 17 августа 2010

Я создаю приложение для просмотра PDF. мои навыки находятся на среднем уровне LOL вуду сейчас ... Я очень далеко справился с этим приложением, но я довольно застрял в своей теории или в своем коде. Мое приложение имеет вид прокрутки с разбивкой по страницам, который сам по себе равен длине всего документа PDF, а затем показывает текущую страницу в другом виде прокрутки (ImageScrollView), который является его собственным классом. ImageScrollView делает UIView, который делает обычные вещи CATiledLayer, и все это отлично работает! :)

Мой ImageScrollView показывает экранную страницу (при переходе к следующей странице ImageScrollView снова загружает на экран CATiledLayer, и вы можете видеть плитки). Я изучал вопрос о том, как сделать так, чтобы страницы слева и справа от текущей страницы были предварительно загружены (поскольку я не думаю, что загрузка PDF в виде плиток на экране будет полезна для пользователей), но я не уверен, что я Я думаю об этом правильно.

Может быть, я должен сделать левый и правый UIView, который будет сидеть рядом с экранным UIView в ImageScrollView?

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

- (void)tilePages {
// Calculate which pages are visible
CGRect visibleBounds = pagingScrollView.bounds;//CGRect visibleBounds =     CGRectMake(0.0f, 0.0f, 320.0f * [self pdfPageCount], 435.0f);
int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
int lastNeededPageIndex  = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds));


firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
lastNeededPageIndex  = MIN(lastNeededPageIndex, [self pdfPageCount] - 1);

// Recycle no-longer-visible pages 
for (ImageScrollView *page in visiblePages) {

    if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex) {
        [recycledPages addObject:page];
        [page removeFromSuperview];}}
[visiblePages minusSet:recycledPages];

// add missing pages
for (int index = firstNeededPageIndex; index <= lastNeededPageIndex; index++) {
    if (![self isDisplayingPageForIndex:index]) {
        ImageScrollView *page = [self dequeueRecycledPage];
        if (page == nil) {
            page = [[[ImageScrollView alloc] init] autorelease];}
        [self configurePage:page forIndex:index];
        [pagingScrollView addSubview:page];
        [visiblePages addObject:page];}}}

Я изменил код, чтобы увидеть, что произошло ниже (не уверен), также я получаю ошибку: инициализация делает указатель из целого числа без приведения

- (void)tilePages:(NSUInteger) index {                
// Calculate which pages are visible
CGRect visibleBounds = pagingScrollView.bounds;
int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
int lastNeededPageIndex  = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds));
firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
lastNeededPageIndex  = MIN(lastNeededPageIndex, [self pdfPageCount] - 1);
// Recycle no-longer-visible pages 
for (ImageScrollView *page in visiblePages) {
    if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex) {
// visible N/Ppages *start*
if (index == 1) {
ImageScrollView *Npage = Npage.index +1;
Npage = [[[ImageScrollView alloc] init] autorelease];
[self configurePage:Npage forIndex:index +1];
[pagingScrollView addSubview:Npage];
[visiblePages addObject:Npage];}
if (index < 2 || index > [self pdfPageCount] -2) {
ImageScrollView *Ppage = Ppage.index -1;
ImageScrollView *Npage = Npage.index +1;
Ppage = [[[ImageScrollView alloc] init] autorelease];
[self configurePage:Ppage forIndex:index -1];
[pagingScrollView addSubview:Ppage];
[visiblePages addObject:Ppage];
Npage = [[[ImageScrollView alloc] init] autorelease];
[self configurePage:Npage forIndex:index +1];
[pagingScrollView addSubview:Npage];
[visiblePages addObject:Npage];}
if (index == [self pdfPageCount] -1) {
ImageScrollView *Ppage = Ppage.index -1;
Ppage = [[[ImageScrollView alloc] init] autorelease];
[self configurePage:Ppage forIndex:index -1];
[pagingScrollView addSubview:Ppage];
[visiblePages addObject:Ppage];}
// visible N/Ppages *end*
        [recycledPages addObject:page];
        [page removeFromSuperview];}}
[visiblePages minusSet:recycledPages];
// add missing pages
for (int index = firstNeededPageIndex; index <= lastNeededPageIndex; index++) {
// recycled N/Ppages *start*
if (index == firstNeededPageIndex +1) {
ImageScrollView *Npage = Npage.index +1;
[recycledPages addObject:Npage];
[Npage removeFromSuperview];}
if (index < firstNeededPageIndex +2 || index > lastNeededPageIndex -2) {
ImageScrollView *Ppage = Ppage.index -1;
ImageScrollView *Npage = Npage.index +1;
[recycledPages addObject:Ppage];
[Ppage removeFromSuperview];
[recycledPages addObject:Npage];
[Npage removeFromSuperview];}
if (index == lastNeededPageIndex -1) {
ImageScrollView *Ppage = Ppage.index -1;
[recycledPages addObject:Ppage];
[Ppage removeFromSuperview];}
// recycled N/Ppages *end*
    if (![self isDisplayingPageForIndex:index]) {
        ImageScrollView *page = [self dequeueRecycledPage];
        if (page == nil) {
            page = [[[ImageScrollView alloc] init] autorelease];}
        [self configurePage:page forIndex:index];
        [pagingScrollView addSubview:page];
        [visiblePages addObject:page];}}}

Могу ли я хранить 3 страницы PDF в NSIndex? например: previousPageToRecycle, previousPage, currentPage, nextPage, nextPageToRecycle

Я не уверен, как это сделать.

1 Ответ

0 голосов
/ 17 августа 2010
ImageScrollView *Ppage = Ppage.index -1;

Ppage.index -1 является целым числом.Вы назначаете его переменной типа ImageScrollView *, которая должна волшебным образом превратить его в указатель.Вероятно, это ошибка.

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

Второй бит кода совершенно не читается из-за отсутствиявменяемый отступ.Есть также некоторые проблемы:

  • слишком много особых случаев .Упростите свою логику;это делает ваш код легче, чтобы получить правильный и легче поддерживать.
  • Существует много дублированного кода.Это связано со специальным регистром.
  • Я не могу на всю жизнь понять, почему firstNeededPageIndex + 1 и lastNeededPageIndex-1 являются специальными.
  • Я бы не использовал NSSet длятак мало страниц.Я не думаю, что возможность использовать minusSet: является значительным преимуществом по сравнению с использованием только removeObject: (и если вы беспокоитесь о производительности, просто используйте removeObjectIdenticalTo:)

Я не уверен, чтоВы имеете в виду «хранение страниц в NSIndex»;Вы имеете в виду CFIndex или NSInteger?


А теперь общий ответ:

В общем, вы на правильном пути, но вам нужно загрузить до пять страниц:

  • Текущая страница, i .
  • Страницы i-1 и i + 1.Пользователь может начать прокрутку в любое время;Вы не хотите, чтобы отображение задерживалось, когда вы рендерили некоторые плитки.
  • Страницы i-2 и i + 2.Бодрая прокрутка означает, что если пользователь прокручивает от i до i + 1, он покажет несколько пикселей i + 2.Вы не хотите загружать страницы во время анимации прокрутки, иначе она будет зависать (если только вы не можете заставить ее загружаться в фоновом потоке).Обратите внимание, что если пользователь прокручивает от i до i + 1 до i + 2, он будет «подпрыгивать» при i + 3.Вы можете загрузить больше, но я считаю это достаточно необычным, чтобы оправдать небольшую задержку.

Я реализовал это, используя кольцевой буферный массив размером 8;страница i сохраняется в ring[i%8], если она загружена.Поскольку мне нужно только 5 страниц одновременно, 8 - это достаточно;по общему признанию, есть большая куча кода управления кольцевым буфером, который вам нужно понять правильно (в основном это занимает некоторое время для кодирования).

Я также просто использовал «текущую страницу», загружая i ± 1 во времяпрокрутка (надеюсь, они уже загружены) и ± 2 при viewDidAppear: и в конце прокрутки (scrollViewDidEndDragging: willDecelerate: with decelerate = NO и scrollViewDidEndDecelerating:).

Вы также можете захотетьдержитесь за представления немного дольше (предварительная загрузка i ± 2, но сохраняйте i ± 3, если они загружены), в противном случае представления будут перезагружаться без необходимости, если пользователь перемещается назад и вперед во время прокрутки (laaaaaag).

Если вы показываете номер страницы, вы также можете добавить гистерезис.Я менял страницы только тогда, когда пользователь прокручивал 2/3 пути на следующую страницу (это означает, что для переключения между двумя страницами пользователь должен перемещаться вперед и назад на 1/3 страницы).Если вы реализуете гистерезис, предыдущий абзац не имеет большого значения.

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