У меня есть NSTableView, который я использую для экспериментов с сортировкой столбцов.Столбцы строки, целого числа и даты, кажется, работают нормально, но десятичный столбец вызывает сбой, над которым я почесал голову.
Вот структура данных:
class LearningStruct : NSObject, Decodable {
@objc var ID : Int
@objc var Text : String
@objc var Description : String
@objc var CreationDate : Date
@objc var UpdateDateTime : Date?
@objc var ValueX: Decimal
@objc var IsTrue : Bool
}
(обратите внимание на использование @objc и NSObject, очевидно, Swift не может обрабатывать кодирование значения ключа, необходимое для сортировки)
Я создаю некоторые тестовые данные JSON:
let learningJSON = "{\"Items\": [{\"ID\": 1, \"Text\": \"Item 1 text\", \"Description\": \"This is item 1 description\", \"CreationDate\": \"02/17/2019\", \"ValueX\": 123.45, \"UpdateDate\": \"02/17/2019\", \"IsTrue\": true}, {\"ID\": 2, \"Text\": \"Item 2 text\", \"Description\": \"This is item 2 description\", \"CreationDate\": \"02/14/2019\", \"ValueX\": 789.01, \"UpdateDate\": \"02/14/2019\", \"IsTrue\": false}]}"
internal var learningItems = [LearningStruct]()
Затем я использую декодер для заполнения массива:
let decoder = JSONDecoder()
let dateformatter = DateFormatter()
dateformatter.dateFormat = "MM/dd/yyyy" // "MM/dd/yyyy'T'HH:mm:ss"
decoder.dateDecodingStrategy = .formatted(dateformatter)
decoder.keyDecodingStrategy = .convertFromSnakeCase
let learningData = try decoder.decode(LearningItems.self, from: learningJSON.data(using: .utf8)!) as LearningItems
learningItems = learningData.Items
У идентификатора NSTableColumns для имени свойства в раскадровке установлено значение для имени свойстваmapping.
for prop in properties {
let colindex = learningTableView.column(withIdentifier: NSUserInterfaceItemIdentifier.init(prop)) // Get the column index number for that property key
if (colindex >= 0) { // If the column exists
let descriptorID = NSSortDescriptor(key: prop, ascending: true)
learningTableView.tableColumns[colindex].sortDescriptorPrototype = descriptorID
}
}
Вот логика сортировки:
/// Sorting logic
func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
print("--- Sorting logic begin ---")
// Debug print the sorters
for col in learningTableView.tableColumns {
if col.sortDescriptorPrototype != nil {
let sorter = col.sortDescriptorPrototype!.key!
let direction = col.sortDescriptorPrototype!.ascending
print("Column \(col.identifier.rawValue): sort descriptor: \(sorter), is ascending: \(direction)")
} else {
print("Column \(col.identifier.rawValue): no sort descriptor")
}
}
print("+++ Sort descriptors list")
let learningItemsMutable = NSMutableArray(array: learningItems)
let sorters = tableView.sortDescriptors
for sortdesc in sorters {
print("Sort descriptor: \(sortdesc.key!)")
}
print("Sorting...")
learningItemsMutable.sort(using: sorters)
learningItems = learningItemsMutable as! [LearningStruct]
tableView.reloadData()
print("--- Sorting logic end ---")
}
Когда я запускаю код, он отлично сортирует все, когда я нажимаю на столбец, пока не доберусь до столбца «ValueX»,В приведенном ниже примере я кликаю по каждому столбцу по порядку, заканчиваясь на «Значение X».Когда я нажимаю на это, я получаю исключение, которое на самом деле мне не поможет ... может кто-нибудь помочь?