我有一个包含应用内设置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
时响应速度非常糟糕。
任何想法都会非常感激。
答案 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)。