Сортировка фотографий точно так же, как родное фотоприложение с использованием PhotoKit

Я пытаюсь воспроизвести собственный фотосборщик iOS8, используя фреймворк Photos. У меня возникла проблема с сортировкой.

Допустим, я делаю следующее:

  1. Я редактирую фотографию в приложении «Камера+» и сохраняю ее обратно в галерею.
  2. Мне нравится другое фото.

В родном фотопикере:

  • Все фотографии (даже те, которые я добавила в избранное) будут отсортированы по creationDate
  • Фотография, которую я отредактировал и сохранил, будет внизу, так как она была последней, которую я изменил. Оригинал будет находиться на своем первоначальном месте в соответствии с датой его создания.

В моем приложении я делаю следующее:

PHFetchOptions *options = [PHFetchOptions new];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage];
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:self.assetCollection options:options];

Я сортирую creationDate и получаю следующий результат:

  • Все фотографии (даже те, которые я добавила в избранное) будут отсортированы по creationDate
  • Фотография, которую я отредактировал, будет сразу же после оригинала в соответствии с первоначальной датой создания.

Затем я изменяю свой запрос, поэтому вместо сортировки по creationDate я сортирую по modificationDate. Я получаю следующий результат:

  • Все фото в целом по порядку почти как creationDate
  • Фотография, которую я отредактировал, будет внизу. Это то, что я хочу и люблю в родном приложении.
  • Любимая фотография также будет внизу :-(

Таким образом, кажется, что Apple меняет modificationDate на любимом действии и, возможно, также на других действиях, и это искажает сортировку фотографий.

Как можно получить именно ту сортировку, которую Apple использует в своем родном приложении? Может быть, какое-то умное использование NSSortDescriptor?


person knutigro    schedule 29.07.2015    source источник


Ответы (5)


Я только что узнал, что для копирования точного поведения родного фотосборщика решение состояло в том, чтобы удалить мой пользовательский sortDescriptior и просто использовать PHFetchResult с поведением по умолчанию. Это кажется таким очевидным сейчас, когда я это обнаружил.

person knutigro    schedule 29.07.2015
comment
Проверив это на нескольких устройствах, я вижу случаи, когда порядок неправильный. Похоже, что в iOS 9 невозможно точно сопоставить родное приложение для фотографий. - person jjxtra; 09.02.2016
comment
@jjxtra Можете ли вы сказать, что это за неправильные случаи? - person kolyuchiy; 10.02.2016
comment
На телефоне моей жены у нее около 20 альбомов. И смарт-альбомы, и обычные альбомы возвращаются в другом порядке, хотя и близком к родному приложению для фотографий. - person jjxtra; 10.02.2016
comment
Это перестало работать в ios12. При этом изображения в iCloud всегда появляются сверху, за ними следуют изображения камеры. - person manish; 13.09.2018
comment
Нет, все еще сломан. - person manish; 02.11.2018

Свифт 3

let fetchOptions = PHFetchOptions()
    let sortOrder = [NSSortDescriptor(key: "creationDate", ascending: false)]
    fetchOptions.sortDescriptors = sortOrder
person Felecia Genet    schedule 27.04.2017
comment
Я использовал этот метод для модификацииDate, но не работает и все еще получаю дату создания на фотографиях, почему? пожалуйста, помогите мне - person Saeed Rahmatolahi; 17.07.2017
comment
Это не дает того же результата, что и родное приложение «Фотографии», которое вроде как добавило дату или около того. Для меня только решения, вообще не использующие дескриптор сортировки, привели к тому же результату, что и приложение «Фотографии». - person d4Rk; 11.12.2019

Как упомянул @knutigro, решение состоит в том, чтобы использовать PHFetchResult с параметрами по умолчанию, то есть путем передачи nil для параметра options:

var fetchResult: PHFetchResult!

override func viewDidLoad() {
    super.viewDidLoad()

    fetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: nil)
}

Но следующим шагом будет обращение результатов сортировки таким образом, чтобы самое последнее изображение было первым. Нет простого способа изменить результаты в PHFetchResult, поэтому я использовал следующий метод:

func assetAtIndex(index: Int) -> PHAsset {
    // Return results in reverse order
    return fetchResult[fetchResult.count - index - 1] as! PHAsset
}
person Jawwad    schedule 22.09.2016
comment
Вы думаете, можно с уверенностью сказать, что он останется обратным? Кроме того, почему Apple возвращает результаты в обратном порядке? - person Roi Mulia; 31.12.2017
comment
@Husam - На мой взгляд, я не думаю, что они изменят его, поскольку, если бы они это сделали, это сломало бы множество приложений, но, конечно, нет никаких гарантий. - person Jawwad; 05.01.2018
comment
@Jawwad, ты упомянул меня! - person Husam; 05.01.2018

Вы можете попробовать использовать два дескриптора сортировки:

NSSortDescriptor sortDesc1 = [NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]]; 

NSSortDescriptor sortDesc2 = [NSSortDescriptor sortDescriptorWithKey:@"modificationDate" ascending:NO]];     

options.sortDescriptors = @[sortDesc1, sortDesc2];

Не проверял, просто подумал, может сработает.

person Tushar    schedule 29.07.2015
comment
Да, спасибо, возможно, это какой-то пользовательский NSSortDescriptor, но простое добавление двух дескрипторов, как вы сделали здесь, в этом случае не работает. Я предполагаю, что второй будет применяться только в том случае, если первый равен при сравнении двух объектов. Даты никогда не совпадают на фотографиях. - person knutigro; 29.07.2015
comment
Не работает, а загруженные из Интернета фотографии, созданные несколькими годами ранее, отображаются не в том месте. - person jjxtra; 09.02.2016
comment
@jjxtra ты уже нашел какое-нибудь решение для этого? - person Faris Muhammed; 13.10.2020

Не спрашивайте меня, почему и как, но когда я устанавливаю такое описание. Он работает как приложение «Фотографии» (Recents).

        [options setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"burstIdentifier" ascending:NO]]];

Попробуй.

person MeGaPk    schedule 19.02.2020
comment
Это не работает. - person sabiland; 20.04.2021