UICollectionView第一次加载时有明显的滞后

时间:2014-04-01 14:01:59

标签: ios iphone uicollectionview viewdidload viewwillappear

我有一个包含应用内设置Table View Controller的简单应用程序。当用户选择" App主题"单元格,segues(推送)到UICollectionView中嵌入的UIViewController

这是12个3x4方式的单元格,其中每个单元格都有图像,标签和复选标记图像(如果已选择该主题)。

这里的单元格是在类中动态加载的,但是当我第一次看到这个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方法而没有其他代码,但在第一次转到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时响应速度非常糟糕。

任何想法都会非常感激。

3 个答案:

答案 0 :(得分: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;
        });

    });

答案 1 :(得分:1)

首先,你不能重复使用你的#34; 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方法中是多余的。如果删除它,它不应该破坏任何东西。

答案 2 :(得分:1)

首先,您应该重复使用细胞,方法是在细胞类型中加点:

而不是此代码

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)。

相关问题