2012-05-11 97 views
0

我已經實現了帶分頁的滾動視圖以在整頁上的一些圖像(圖形)之間滾動(如安裝在iPhone中的照片應用程序)。圖像滾動視圖崩潰

我發現下面的代碼使用經典的3頁解決方案(我爲我的應用程序做了一些小的修改),但即使它「工作」,滾動似乎很慢,並且經常在滾動一些圖像應用程序崩潰。

我正在使用Xcode 4.2,並啓用ARC選項並在iPad設備上測試這兩個選項。 圖片(10 jpg)爲2048x1539,平均尺寸爲200/250Kb。

有沒有人能幫我找到問題的原因?

感謝, 科拉多

const int numImages = 10; 
const float kPageWidth = 1024.0f; 
const float kPageHeight = 768.0f; 


- (void)viewDidLoad { 
[super viewDidLoad]; 

    scroll.contentSize = CGSizeMake(kPageWidth * numImages, kPageHeight); 
imageview1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kPageWidth, kPageHeight)]; 

imageview2 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth, 0, kPageWidth, kPageHeight)];  

imageview3 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth * 2, 0, kPageWidth, kPageHeight)]; 

scroll.contentOffset = CGPointMake(0, 0); 

[imageview1 setImage:[UIImage imageNamed:@"grafico_0.jpg"]]; 
imageview1.contentMode = UIViewContentModeScaleAspectFit; 
[imageview1 setTag:1]; 

imageview2.contentMode = UIViewContentModeScaleAspectFit; 
[imageview2 setTag:2]; 

imageview3.contentMode = UIViewContentModeScaleAspectFit; 
[imageview3 setTag:3]; 

[scroll addSubview:imageview1]; 
[scroll addSubview:imageview2]; 
[scroll addSubview:imageview3];   
} 


- (void)scrollViewDidScroll:(UIScrollView*)scrollView { 

const CGFloat currPos = scrollView.contentOffset.x; 
const NSInteger selectedPage = lroundf(currPos * (1.0f/kPageWidth)); 
const NSInteger zone = 1 + (selectedPage % 3); 
const NSInteger nextPage = selectedPage + 1; 
const NSInteger prevPage = selectedPage - 1; 

/// Next page 
if (nextPage < numImages) 
{ 
    NSInteger nextViewTag = zone + 1; 
    if (nextViewTag == 4) 
     nextViewTag = 1; 

    UIImageView* nextView = (UIImageView*)[scrollView viewWithTag:nextViewTag];  
    nextView.frame = (CGRect){.origin.x = nextPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth}; 

    NSString *str = [NSString stringWithFormat:@"grafico_%d.jpg", nextPage]; 
    UIImage* img = [UIImage imageNamed:str]; 
    nextView.image = img; 
} 


/// Prev page 
if (prevPage >= 0) 
{ 
    NSInteger prevViewTag = zone - 1; 
    if (!prevViewTag) 
     prevViewTag = 3; 

    UIImageView* prevView = (UIImageView*)[scrollView viewWithTag:prevViewTag];  
    prevView.frame = (CGRect){.origin.x = prevPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth}; 

    NSString *str = [NSString stringWithFormat:@"grafico_%d.jpg", prevPage]; 
    UIImage* img = [UIImage imageNamed:str]; 
    prevView.image = img; 
} 

} 

回答

1

你不應該使用imageNamed:您的大圖片加載,因爲該方法緩存圖像,應該只用於您在應用程序中使用多次的小圖片(如按鈕等圖像)。這種方法在與許多大型圖像一起使用時會導致內存問題而臭名昭着。

改爲使用imageWithContentsOfFile:。使用該方法加載圖像可確保圖像不會被緩存,並且在不再使用該圖像後會釋放內存。

如果滾動似乎是緩慢的,你可以使用performSelectorInBackground移動圖像的後臺線程的負載:

[self performSelectorInBackground:@selector(retrieveImageData:) withObject:imagePath]; 

中的UIImage的負荷發生在這個方法:

- (void)retrieveImageData:(NSString *)imagePath { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath]; 
    [self performSelectorOnMainThread:@selector(imageDataRetrieved:) withObject:image waitUntilDone:NO]; 
    [pool release]; 
} 

並將圖像附加到主線程上的UIImageView(UI操作不得發生在後臺線程上):

- (void)imageDataRetrieved:(UIImage)*image { 
    yourImageView.image = image; 
} 
+0

謝謝,我用imageWithContentsOfFile替換ImageNamed,即使滾動仍然很慢,應用程序也不會崩潰。 – Corrado

+0

你像我在我的回答中描述的那樣加載圖像嗎? 「滾動很慢」是什麼意思?當新圖像加載時,滾動停止一毫秒?或者你一次只能滾動一張圖片? – joern

+0

我的意思是圖像之間的過渡似乎很緩慢。我將圖像的大小減少到了1024x768,並且它有點更好(2048x1539(250Kb)的圖像太大了?)。我也試圖理解你的第二個解決方案,但它不是很清楚(我的第一個應用程序!)。 – Corrado