我是Objective C和iOS编程的新手,并且已经徘徊在我脑海中的水域。任何帮助表示赞赏。
我在排序要在UITableView中使用的数组时遇到问题。基本上,我想查询一组相册,并根据用户设置按字母顺序或按日期(升序和降序)排序。首先我合成了一些全局数组,并且媒体查询了这些专辑:
@synthesize allSongs, arrayForTableView;
MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
[songsQuery setGroupingType: MPMediaGroupingAlbum];
arrayForTableView = [songsQuery collections];
allSongs = [songsQuery items];
到目前为止,这么好。相册按字母顺序排序,就像他们应该的那样。 allSongs数组用于其他地方的一些回放功能。所以现在,我添加了对设置的检测,并按照"年"进行排序。属性:
@synthesize allSongs, arrayForTableView;
MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
[songsQuery setGroupingType: MPMediaGroupingAlbum];
NSArray *allAlbums = [songsQuery collections];
allSongs = [songsQuery items];
if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"SortAlbumsMethod"] isEqualToString:@"0"]) {
arrayForTableView = [songsQuery collections];
} else if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"SortAlbumsMethod"] isEqualToString:@"1"]) {
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"year"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
arrayForTableView = [allAlbums sortedArrayUsingDescriptors:sortDescriptors];
} else {
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"year"
ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
arrayForTableView = [allAlbums sortedArrayUsingDescriptors:sortDescriptors];
}
这是我遇到问题的地方。以上内容不起作用,因为每个集合(专辑)都没有年份属性。如果我更换" allAlbums"用" allSongs,"代码正常运行。 除了,我现在每首歌都有一个条目。显示的标签信息仅与相册相关,导航基于AlbumPersistentID,所以一切都很好,我只是有太多重复的条目(看起来相同,因为歌曲名称没有显示)。
似乎显而易见的解决方案是创建一个数组,让我们称之为" albumRepresentatives"使用" allAlbums"中每个集合中的单个项目,并在排序描述符中使用它。每个项目实际上都是一首歌而不是专辑,但外观和功能仍然有效。理想情况下,我想比较每张专辑中的所有歌曲,选择一个具有最高"年份"属性并将其添加到" albumRepresentatives"。 B计划就是为每个专辑集合简单地将索引为0的歌曲。
问题是,实际上正在做,这在我的能力范围之外。任何帮助将不胜感激!
答案 0 :(得分:0)
一个选项可能是使用set,因为它们不存储重复的对象并使用数组的内容初始化它。您可能需要覆盖(可能添加到类别)isEqual来实现它。
第二个选项:
//Could be added as category to MPMediaItem for example
+(MPMediaItem*)latestSongInAlbum:(NSArray*)songsInAlbum
MPMediaItem *latestSong = nil;
for (MPMediaItem *song in songsInAlbum) {
if(!latestSong) {
latestSong = song;
} else if([[latestSong valueForProperty: MPMediaItemPropertyReleaseDate] compare:
[song valueForProperty: MPMediaItemPropertyReleaseDate]] == NSOrderedAscending]) {
latestSong = song;
}
}
return latestSong;
}
做类似于这个伪代码的事情:
NSMutableArray* latestSongFromeachAlbum = [[NSMutableArray alloc] initWithCapacity:[allAlbums count]];
for( album in allAlbums) {
NSIndexSet* indexes = [allSongs indexesOfObjectsPassingTest:(^)(id obj, NSUInteger idx, BOOL *stop)) {
return album == obj.album;
}];
NSArray* songsInAlbum = [allSongs objectsAtIndexes:indexes];
MPMediaItem* latestSong = [ExtendedClass latestSongInAlbum:songsInAlbum];
//now you have pair latestSong(you can use it's date) in album and the album. You can store as you prefer
[latestSongFromeachAlbum addObject:latestSong];
}
希望它足够完整。