#cocoa #sorting #swift #nstableview
#cocoa #сортировка #swift #nstableview
Вопрос:
Я использую view-based NSTableView
в своем приложении Cocoa, написанном на Swift, и хочу реализовать функцию сортировки по двум столбцам таблицы. Однако в Objective-C это можно реализовать, сначала установив «Ключ сортировки» в инспекторе атрибутов, а затем внедрив метод делегирования источника данных с именем tableView: sortDescriptorsDidChange:
.
Однако этот метод принимает sortDescriptor
в качестве параметра и позволяет разработчикам использовать его внутри метода, например:
- (void) tableView:( NSTableView *) tableView sortDescriptorsDidChange:( NSArray *) oldDescriptors {
[self.songs sortUsingDescriptors:tableView.sortDescriptors];
[tableView reloadData];
}
Однако в Swift Array нет такого метода, как sortUsingDescriptors
. Итак, сначала я попытался преобразовать Array
в NSMutableArray
, чтобы использовать метод NSMutableArray
‘s, но поскольку мой массив Swift определен как AnyObject[]
, его нельзя преобразовать в NSMutableArray
.
Итак, как мне реализовать функциональность сортировки в табличном представлении в Swift? Я знаю, что Swift Array может использовать sort
функцию для сортировки объекта путем сравнения двух аргументов и возврата значений bool, но можно ли ее использовать sortDescriptors
для сортировки таблицы? Или я должен просто игнорировать sortDescriptors
аргумент и вместо этого написать свою собственную логику сортировки вручную? (но тогда я не знаю, как определить, на какой столбец нажат, без sortDescriptors
значения).
Ответ №1:
Вероятно, лучший способ, по крайней мере прямо сейчас, сначала преобразовать его в NSMutableArray
, а затем отсортировать с помощью NSMutableArray
sortUsingDescriptors
метода и, наконец, преобразовать его обратно в исходный массив, вот так:
func tableView(tableView: NSTableView!, sortDescriptorsDidChange oldDescriptors: [AnyObject]) {
var songsAsMutableArray = NSMutableArray(array: songs)
songsAsNSMutableArray.sortUsingDescriptors(tableView.sortDescriptors)
songs = songsAsNSMutableArray
tableView.reloadData()
}
Кстати, var songsAsMutableArray = songs as NSMutableArray
вызывает ошибку: NSArray is not a subtype of NSMutableArray
, поэтому я создал NSMutableArray
экземпляр, как показано выше.
Комментарии:
1. Я тоже пришел к этому решению, но все новые Swift (что за название, быстро меняющий свой синтаксис изо дня в день) теперь поставляются с
*** NSForwarding: warning: object 0x.. of class '...' does not implement methodSignatureForSelector: -- trouble ahead
. Попытка добавить этот метод приводит к появлению еще более неудобных сообщений. Ваш код все еще работает?2. Неважно. Понял это сразу после комментария: просто используйте YourArray.sort, правильно обрамляя старые описания.
3. Успешно сделал это в Swift 4 — небольшая модификация, теперь это «сортировка (с использованием: дескрипторов)». Итак, с моим массивом данных о версиях, хранящихся в моем классе «IdbVersionInfo», это выглядит так:
func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) { if versions != nil { let versionsAsNSMutable = NSMutableArray(array: versions!) versionsAsNSMutable.sort(using: table.sortDescriptors) versions = versionsAsNSMutable as? Array<IdbVersionInfo> } tableView.reloadData() }
Отлично работает!