RootViewController - tableView:cellForRowAtIndexPath - 从 assetLibrary 加载图像
StackOverflow 的朋友和同事程序员,
我的 RootViewController(视图上的 FlowerTableView)应该显示带有标题、副标题和图像缩略图(从相机胶卷加载)的单元格。我想这是一个非常基本的表格。
所有内容都存储在“核心数据”中,但图像存储为相机胶卷的图像路径。示例:flower.imagePath = assets-library://asset/asset.JPG?id=1000000002&ext
使用底部的代码,一切都应该顺利运行,但事实并非如此。启动应用程序时,会显示标题和副标题,但不会显示图像。当我按下一个单元格(显示详细视图)并再次弹出到主视图时,会显示该特定单元格的图像。
当我按下“显示全部”(工具栏上的一个按钮,该按钮执行以下代码
NSFetchRequest *fetchRequest = [[self fetchedResultsController] fetchRequest];
[fetchRequest setPredicate:nil];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.flowerTableView reloadData];
并重新加载表格)时,现在会显示所有美丽的花朵。
为什么第一次没有放花呢?这是缓存问题吗?
调试此代码时,字符串:“此调试字符串在完成此功能后被记录”是在启动应用程序加载表格后记录的,而不是在按“显示全部”后记录的 这意味着所有图像均已从相机胶卷成功加载,但在显示单元格后附加到单元格,因此未显示。
当按“显示全部”时,会按预期打印同一行
希望有人能告诉我这里发生了什么,甚至更好的是,要在我的代码中更改哪些内容才能使这项工作正常进行。我现在被困住了...
感谢您帮助我! 埃德温
::代码:::
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath
{
Flower *flower = [fetchedResultsController_ objectAtIndexPath:indexPath];
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
// Display the image if one is defined
if (flower.imagePath && ![flower.imagePath isEqualToString:@""])
{
// Should hold image after executing the resultBlock
__block UIImage *image = nil;
ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset *asset)
{
NSLog(@"This debug string was logged after this function was done");
image = [[UIImage imageWithCGImage:[asset thumbnail]] retain];
};
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error)
{
NSLog(@"Unresolved error: %@, %@", error, [error localizedDescription]);
};
[assetsLibrary_ assetForURL:[NSURL URLWithString:flower.imagePath]
resultBlock:resultBlock
failureBlock:failureBlock];
[cell.imageView setImage:image];
}
return cell;
}
StackOverflow friends and colleague programmers,
My RootViewController (a flowerTableView on a view) should display cell's with title, subtitle and an image thumbnail (loaded from the camera roll). A very basic table I guess.
All content is stored in 'Core Data' but the images are stored as imagePaths to the camera roll. Example: flower.imagePath = assets-library://asset/asset.JPG?id=1000000002&ext
Using the code at the bottom everything should run smoothly but it doesn't . When starting the App the title's and subtitle's are shown, but the images are not. When I press a cell, which display's the detail view, and pop back again to the main view the image for this specific cell is shown.
When I press 'Show All', a button on a toolbar which executes the following code
NSFetchRequest *fetchRequest = [[self fetchedResultsController] fetchRequest];
[fetchRequest setPredicate:nil];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.flowerTableView reloadData];
and reloads the table, all the beautiful flowers are now shown.
Why didn't the flowers be displayed the first time? Is this a caching problem?
When debugging this code the string: 'This debug string was logged after this function was done' was logged after loading the table on starting the app, not after pressing 'Show All'
This means that all images are loaded from the camera roll successfully but attached to the cell after the cell was displayed and therefore not shown.
The same line is printed as intended when pressing 'Show All'
Hope someone can tell me what's going on here and even better, what to change in my code to make this work. I'm stuck at the moment...
Thank for helping me out!
Edwin
:::THE CODE:::
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath
{
Flower *flower = [fetchedResultsController_ objectAtIndexPath:indexPath];
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
// Display the image if one is defined
if (flower.imagePath && ![flower.imagePath isEqualToString:@""])
{
// Should hold image after executing the resultBlock
__block UIImage *image = nil;
ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset *asset)
{
NSLog(@"This debug string was logged after this function was done");
image = [[UIImage imageWithCGImage:[asset thumbnail]] retain];
};
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error)
{
NSLog(@"Unresolved error: %@, %@", error, [error localizedDescription]);
};
[assetsLibrary_ assetForURL:[NSURL URLWithString:flower.imagePath]
resultBlock:resultBlock
failureBlock:failureBlock];
[cell.imageView setImage:image];
}
return cell;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
-[ALAssetsLibrary assetForURL:resultBlock:failureBlock] 异步运行。这意味着调用会立即在 tableView:cellForRowAtIndexPath: 方法中返回。在实际加载资源之前,该单元格会显示在表视图中。
您需要做的是设置结果块中单元格的图像。像这样的事情:
-[ALAssetsLibrary assetForURL:resultBlock:failureBlock] runs asynchronously. That means that the call returns immediately in your tableView:cellForRowAtIndexPath: method. The cell is displayed in the table view before the actual loading of the asset has taken place.
What you need to do is set the image for the cell in the result block. Something like this:
溢出主义者让我提出以下解决方案:
不要在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath 中创建单元格,而是
创建一个填充有 UITableViewCells 的 NSMutableArray (与您在 cellForRowAtIndexPath 方法中创建的单元格相同)您想要在表格中显示的内容
并简单地在 cellForRowAtIndexPath 方法中返回相关的 UITableViewCell (这将是 NSMutableArray 中的一个对象)。
这样,cellForRowAtIndexPath 方法将显示已经加载并准备显示的单元格。
Fellow Overflowist let me propose the following solution:
rather than creating your cells in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath
create an NSMutableArray populated with UITableViewCells (the same ones you create in the cellForRowAtIndexPath method) that you want to display in the table
and simply return the relevant UITableViewCell (which will be an object in the NSMutableArray) in the cellForRowAtIndexPath method.
This way the cellForRowAtIndexPath method will show cells which have already been loaded and are ready to be shown.