2014-04-01 95 views
0

我有一個簡單的應用程序,其中包含應用內設置Table View Controller。當用戶選擇「應用主題」單元格時,它將segues(推送)嵌入到UIViewController中的UICollectionViewUICollectionView首次加載明顯延遲

這是12x3x4時尚單元格,其中每個單元格都有圖像,標籤和複選標記圖像(如果已選擇該主題)。

細胞在這裏是動態加載的,但是當我第一次繼續這個UICollectionView時,我注意到了一些重大的延遲。隨後的每一次,它都能正常工作,但在iPhone 5s上,有一些極端明顯的滯後,我對iOS開發相當陌生,我有一種感覺,這與第一次創建視圖的方式有關,但我我不確定。

在我viewDidLoad,我有:

- (void)viewDidLoad 
{ 
    self.title = @"Themes"; 
    self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]}; 
    [super viewDidLoad]; 
    self.cView.dataSource = self; 
    self.cView.delegate = self; 


    self.themeLabels = [[NSArray alloc] initWithObjects:@"Original", @"Peacock", @"Mystical", @"Zebra", @"Simplicity", @"Rainbow", @"Prosperity", @"Leopard", @"Hypnotic", @"Dunes", @"Twirl", @"Oceanic", nil]; 

    self.themeImages = @[[UIImage imageNamed:@"Newiphonebackground.png"], [UIImage imageNamed:@"peacock.png"], [UIImage imageNamed:@"Purplepink.png"], [UIImage imageNamed:@"PinkZebra.png"], [UIImage imageNamed:@"Greenish.png"], [UIImage imageNamed:@"MarblePrint.png"], [UIImage imageNamed:@"Prosperity.png"], [UIImage imageNamed:@"leopard.png"], [UIImage imageNamed:@"CircleEffect.png"], [UIImage imageNamed:@"Orange3.png"], [UIImage imageNamed:@"ReddishBlack.png"], [UIImage imageNamed:@"bluey.png"]]; 

    [self changeAppThemes]; 

} 

的changeAppThemes方法基本上是通過和NSUserDefaults的循環眼看要應用的主題。

- (void)changeAppThemes 
{ 
    self.selectedTheme = [[NSUserDefaults standardUserDefaults] objectForKey:@"Theme"]; 

    if ([self.selectedTheme isEqualToString:@"Mystical"]) 
    { 
     self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Purplepink.png"]]; 
     UIImage *navBackgroundImage = [[UIImage imageNamed: @"Purplepinknav"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 
     [self.navigationController.navigationBar setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault]; 

     UIImage *tabBackground = [[UIImage imageNamed:@"SolidPurple.png"] 
            resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 
     [self.tabBarController.tabBar setBackgroundImage:tabBackground]; 
    } 

etc 

viewWillAppear是:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self changeAppThemes]; 

    self.selectedThemeString = [[NSUserDefaults standardUserDefaults] objectForKey:@"Selection"]; 

    if ([self.selectedThemeString isEqualToString:@"Original"]) 
    { 
     self.checkedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 
    } 

    else if ([self.selectedThemeString isEqualToString:@"Oceanic"]) 
    { 
     self.checkedIndexPath = [NSIndexPath indexPathForRow:11 inSection:0]; 
    } 

    [self.cView reloadData]; 

} 

viewWillAppear今天之前只有在調用changeAppThemes方法,無需其他代碼,但segueing到UICollectionView首次當它還是奇慢無比。

cellForItemAtIndexPath是:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 

    ThemeCell *themeCell = (ThemeCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"Theme Cell" forIndexPath:indexPath]; 

    NSString *cellData = [self.themeLabels objectAtIndex:indexPath.row]; 

    themeCell.cellLabel.text = cellData; 
    themeCell.cellImages.image = self.themeImages[indexPath.row]; 
    UIImageView *dot = [[UIImageView alloc]initWithFrame:CGRectMake(5, 0, 1, 2)]; 
    dot.image=[UIImage imageNamed:@"check-white-hi.png"]; 

    if([self.checkedIndexPath isEqual:indexPath]) 
    { 
     NSLog(@"Loaded"); 
     themeCell.backgroundView = dot; 
     [themeCell addSubview:dot]; 

    } 
    else 
    { 
     NSLog(@"Not Loaded"); 

     themeCell.backgroundView = nil; 
    } 

我應該改變,我發出呼叫到changeAppThemes?我已經從viewWillAppear中刪除了該呼叫,並將其留在了viewDidLoad之間,反之亦然,在這兩種情況下,第一次打開UICollectionView時的響應性非常差。

任何想法將非常感激。

+0

檢查你的圖片尺寸 – NeverBe

+0

這實際上是一個非常有趣的觀點。我實際上使用相同的圖像作爲應用程序的背景 - 所以iPhone 5的大小爲640x1136,用於此收藏單元的圖像。現在你已經提到了圖像大小,這似乎有點過分。我應該大量減少圖像的大小並進行測試嗎? – amitsbajaj

+0

使用圖像的大小,你設計它乘以2爲視網膜 – NeverBe

回答

1

首先你不要重複使用你的「themeCell」(至少不可見)。你只應該實例化一次,然後像現在一樣重用它。因此,我建議你添加一個if語句,如:

if(themeCell == nil) { 
    // Do all initialization here. For example the "dot" ImageView... 
} else { 
    // Reuse the "themeCell" here 
} 

也是「self.themeImages」在您的viewDidLoad中可能會增加一些開銷,但它不應該是極致。我們在MAX中討論60-100ms,這在啓動時並不明顯。而另一個大但是: - 這真的取決於你的圖像的大小!如果它們很大,比如說2-5MB,那麼會增加很多開銷,應該通過「延遲加載」來完成。

另外,[self changeAppThemes]在viewDidLoad方法中是多餘的。如果你刪除它,它不應該破壞任何東西。

+0

非常感謝@Alexander W - 我很抱歉回覆晚了。我感謝你的迴應。在編程方面相當新穎,我不太清楚如何使用主題單元格== nil的單元格的重用,因爲當我將imageView實例化代碼放在那裏時,它不會在方法的其他任何地方識別它。但是,我確實減小了圖像的大小,併爲uiimageview創建了一個屬性,並在viewDidLoad中加載並實例化了它。這似乎有很大的不同。我會如何適當地重複使用我的代碼,以便我可以做到這一點? – amitsbajaj

+0

而且我也從viewDidLoad中刪除了自己改變的主題,正如你所提到的那樣,它並沒有對代碼的運行產生影響,但可能會提高速度。我只是想通過重用細胞來做到最正確的方式。 – amitsbajaj

+0

你有以下,'[self.cView registerClass:[ThemeCell類] forCellWithReuseIdentifier:@「主題單元格」];在loadView或viewDidLoad?在你的ThemeCell實現的'initWithFrame:(CGRect)aRect'方法中,你添加了你的單元格的子視圖並且執行例如'UIImageView * dot'的初始化。希望這可以幫助! –

2

異步加載圖像。考慮下面的變化。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 

    dispatch_async(queue, ^{ 
     //Do THIS 
     UIImage *localImage [self createImageObjectsforIndex:indexPath.row]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      //Do this when done 
      cell.image = localImage; 
     }); 

    }); 
+0

非常感謝埃裏克的回覆,並對遲交的回覆表示歉意。我已經縮小了圖像的大小,雖然它有所作爲,但我不確定它是否快100%,所以我一定會按照您的建議異步進行此操作。非常感謝您的答覆。 – amitsbajaj

+0

我希望在這裏使用DISPATCH_QUEUE_PRIORITY_BACKGROUND,因爲以高優先級加載圖像確實影響fps。 – kelin

1

對於你首先應該重用細胞,加入點到細胞propotype和:的

,而不是這個代碼

if([self.checkedIndexPath isEqual:indexPath]) 
{ 
    NSLog(@"Loaded"); 
    themeCell.backgroundView = dot; 
    [themeCell addSubview:dot]; 

} 
else 
{ 
    NSLog(@"Not Loaded"); 

    themeCell.backgroundView = nil; 
} 

使用本:

themeCell.dot.hidden = !([self.checkedIndexPath isEqual:indexPath]); 

其次,調整圖像文件到imageView大小(視網膜x2)。

+0

謝謝@NeverBe--由於某種原因,我無法正常工作,但我對亞歷山大的回答非常感謝。我很感謝你在這個問題上的時間,我已經投了你的答案,因爲它確實指向了我的正確方向。再次感謝 – amitsbajaj