2010-08-16 45 views
0

我正在構建一個pdf查看器應用程序。我的技能現在處於中等的LOL巫術水平......我用這個應用程序自己做了很多,但我的理論或我的代碼相當困難。我的應用程序有一個分頁滾動視圖,它使自己成爲整個pdf文檔的長度,然後在另一個滾動視圖(ImageScrollView)中顯示當前頁面,這是它自己的類。 ImageScrollView使UIView能夠完成CATiledLayer的常規工作,而且一切正常! :)iphone:錯誤和pdf頁面問題

我的ImageScrollView顯示屏幕上的頁面(當您滾動到下一頁時ImageScrollView再次加載CATiledLayer屏幕上,你可以看到瓷磚)。我一直在研究如何讓當前頁面的左右頁面預先加載(因爲我不認爲將PDF加載到屏幕上的瓷磚對用戶體驗有好處),但我不確定是否我正確地思考它。

也許我應該做一個左邊和右邊的UIView坐在ImageScrollView中的屏幕上的UIView?

或者它可能與回收不再可見的頁面(如下所示)有關(但我認爲我仍然需要左側/右側的視圖,甚至仍然不需要回收視圖)

- (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];}}} 

我能存儲在一個NSIndex 3個PDF頁面?例如:previousPageToRecycle,previousPage,currentPage,nextPage,nextPageToRecycle

我不確定如何做到這一點。

回答

0
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(希望它們已經加載),我在viewDidAppear中加載了2:並且在滾動結束時(scrollViewDidEndDragging:willDecelerate:with decelerate = NO和scrollViewDidEndDecelerating :)。

您可能還想繼續觀看更長時間的視圖(預加載i + 2,但如果它們恰好被加載,則保留i + 3),否則如果用戶在滾動過程中前後移動,視圖將不必要地重新加載(laaaaaag)。

如果您顯示一個頁碼,您可能還想添加一些滯後。當用戶將2/3的方式滾動到下一頁(這意味着在兩頁之間切換時,用戶必須前後移動1/3頁)時,我才更改頁面。如果你執行遲滯,上一段就不是什麼大不了的事情。