All tableView Cells Show Same Artwork Image for Pl

2019-09-20 11:35发布

问题:

I have a tableView which shows a list of playlists from the user's music library. The code I used to get this list is:

@implementation playlistsViewController
{
    NSArray *playlists;
    MPMediaQuery *playlistsQuery;
}

- (void)viewDidLoad
{        
    self.title = @"Playlists";

    playlistsQuery = [MPMediaQuery playlistsQuery];
    playlists = [playlistsQuery collections]; 
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [playlists count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{  ....

    // Configure the cell...

    MPMediaItem *rowItem = [playlists objectAtIndex:indexPath.row];

    cell.textLabel.text = [rowItem valueForProperty: MPMediaPlaylistPropertyName];

    cell.imageView.image = [self getAlbumArtworkWithSize:(CGSizeMake(44,44))];

    return cell;
}

I then have getAlbumArtworkWithSize:

- (UIImage *) getAlbumArtworkWithSize: (CGSize) albumSize
{
    // IMAGE

    MPMediaQuery *playlistQuery = [MPMediaQuery playlistsQuery];
    MPMediaPropertyPredicate *playlistPredicate = [MPMediaPropertyPredicate predicateWithValue: playlistTitle forProperty: MPMediaPlaylistPropertyName];
    [playlistQuery addFilterPredicate:playlistPredicate];

    for (MPMediaPlaylist *playlist in playlists) {
        NSLog (@"%@", [playlist valueForProperty: MPMediaPlaylistPropertyName]);

        NSArray *songs = [playlist items];

        for (int i = 0; i < [songs count]; i++) {

            MPMediaItem *mediaItem = [songs objectAtIndex:i];
            UIImage *artworkImage;

            MPMediaItemArtwork *artwork = [mediaItem valueForProperty: MPMediaItemPropertyArtwork];
            tempImage = [artwork imageWithSize: CGSizeMake (1, 1)];

            if (tempImage) {
                tempImage = [artwork imageWithSize:albumSize];
                playlistImage = artworkImage;
                return artworkImage;
            }
        }
    }
return [UIImage imageNamed:@"Songs.png"];
}

What this code does: it cycles through all songs in the playlist until it finds a song with album artwork, as some songs do not have any artwork. Then it returns that image.

However, this only returns the same artwork image for all cells in my table. How do I run getAlbumArtworkWithSize for each table view cell (playlist name)?

This is what I currently get:

.

回答1:

It's because you're not iterating through the collection of items specific to the playlist belonging to that row in your getAlbumArtworkWithSize method. To make it easier and reduce execution time (not making an additional query in your method), try passing the collection to your function:

- (UIImage *)getAlbumArtworkWithSize:(CGSize)albumSize forPlaylist:(MPMediaItemCollection *)collection
{
    for (MPMediaItem *mediaItem in collection.items) {
        UIImage *artworkImage;

        MPMediaItemArtwork *artwork = [mediaItem valueForProperty: MPMediaItemPropertyArtwork];
        tempImage = [artwork imageWithSize: CGSizeMake (1, 1)];

        if (tempImage) {
            tempImage = [artwork imageWithSize:albumSize];
            playlistImage = artworkImage;
            return artworkImage;
        }
    }
    return [UIImage imageNamed:@"Songs.png"];
}

Then use it like so:

cell.imageView.image = [self getAlbumArtworkWithSize:CGSizeMake(44,44) forCollection:[playlists objectAtIndex:indexPath.row]];

I wouldn't recommend using this method, it could prove to be very slow with playlists containing ~1000 items. It's better to use the representative item of the collection and use a placeholder if no image is returned. Which would like something like this:

- (UIImage *)getAlbumArtworkWithSize:(CGSize)albumSize forPlaylist:(MPMediaItemCollection *)collection
{
        UIImage *artworkImage;

        MPMediaItem *mediaItem = [collection representativeItem];
        MPMediaItemArtwork *artwork = [mediaItem valueForProperty: MPMediaItemPropertyArtwork];
        tempImage = [artwork imageWithSize: CGSizeMake (1, 1)];

        if (tempImage) {
            tempImage = [artwork imageWithSize:albumSize];
            playlistImage = artworkImage;
            return artworkImage;
        }
    return [UIImage imageNamed:@"Songs.png"];
}