我有這個實作:
發票 - 保留有關發票的資訊
import Foundation
class Invoice {
var content: String?
var createdAt: Date?
var dateA: Date?
var dateB: Date?
var employee: String?
var expenseCategory: String?
var from: Date?
var id: String?
var ncf: String?
var ncfA: String?
var ncfB: String?
var numeration: Int64
var paymentMethod: String?
var rejectReason: String?
var sessionId: String?
var status: String?
var subtotal: Double
var sync: Bool
var taxExempt: Bool
var taxType: String?
var taxValue: Double
var to: Date?
var total: Double
var totalInvoice: Int64
var typeA: String?
var typeB: String?
var updatedAt: Date?
var user: String?
var toCompany: Company?
var toDocument: [Document]?
var storeId: String?
var incomeType: String?
var expenseType: String?
var toOtherCompany: Company?
var invoiceDate: Date?
var otherTax: Double
var companyId: String?
init(_content: String?, _storeId: String?, _createdAt: Date?, _dateA: Date?, _dateB: Date?, _employee: String?, _expenseCategory: String?,
_from: Date?, _id: String?, _ncf: String?, _ncfA: String?, _ncfB: String?, _numeration: Int64, _paymentMethod: String?,
_rejectReason: String?, _sessionId: String?, _status: String?, _subtotal: Double, _sync: Bool, _taxExempt: Bool, _taxType: String?,
_taxValue: Double, _to: Date?, _total: Double, _totalInvoice: Int64, _typeA: String?, _typeB: String?, _updatedAt: Date?,
_user: String?, _incomeType: String?, _expenseType: String?, _invoiceDate: Date?, _otherTax: Double, _companyId: String?, _toCompany: Company? = nil, _toDocument: [Document]? = nil,
_toOtherCompany: Company? = nil) {
self.content = _content
self.createdAt = _createdAt
self.dateA = _dateA
self.dateB = _dateB
self.employee = _employee
self.expenseCategory = _expenseCategory
self.from = _from
self.id = _id
self.ncf = _ncf
self.ncfA = _ncfA
self.ncfB = _ncfB
self.numeration = _numeration
self.paymentMethod = _paymentMethod
self.rejectReason = _rejectReason
self.sessionId = _sessionId
self.status = _status
self.subtotal = _subtotal
self.sync = _sync
self.taxExempt = _taxExempt
self.taxType = _taxType
self.taxValue = _taxValue
self.to = _to
self.total = _total
self.totalInvoice = _totalInvoice
self.typeA = _typeA
self.typeB = _typeB
self.updatedAt = _updatedAt
self.user = _user
self.toCompany = _toCompany
self.toDocument = _toDocument
self.storeId = _storeId
self.incomeType = _incomeType
self.expenseType = _expenseType
self.toOtherCompany = _toOtherCompany
self.invoiceDate = _invoiceDate
self.otherTax = _otherTax
self.companyId = _companyId
}
// Get the descriptive status
func getDescriptiveStatus() -> String {
switch self.status {
case InvoiceStatus.waiting.toString():
return InvoiceStatus.waiting.description.uppercased()
case InvoiceStatus.processing.toString():
return InvoiceStatus.processing.description.uppercased()
case InvoiceStatus.processed.toString():
return InvoiceStatus.processed.description.uppercased()
case InvoiceStatus.pending_rejection.toString():
return InvoiceStatus.pending_rejection.description.uppercased()
case InvoiceStatus.rejected.toString():
return InvoiceStatus.rejected.description.uppercased()
case InvoiceStatus.posted.toString():
return InvoiceStatus.posted.description.uppercased()
case InvoiceStatus.reviewing.toString():
return InvoiceStatus.reviewing.description.uppercased()
case InvoiceStatus.pending_upload.toString():
return InvoiceStatus.pending_upload.description.uppercased()
default:
return "UNKNOW STATUS"
}
}
// Get status (based in enum)
func getStatus() -> InvoiceStatus? {
switch self.status {
case InvoiceStatus.waiting.toString():
return InvoiceStatus.waiting
case InvoiceStatus.processing.toString():
return InvoiceStatus.processing
case InvoiceStatus.processed.toString():
return InvoiceStatus.processed
case InvoiceStatus.pending_rejection.toString():
return InvoiceStatus.pending_rejection
case InvoiceStatus.rejected.toString():
return InvoiceStatus.rejected
case InvoiceStatus.posted.toString():
return InvoiceStatus.posted
case InvoiceStatus.reviewing.toString():
return InvoiceStatus.reviewing
case InvoiceStatus.pending_upload.toString():
return InvoiceStatus.pending_upload
default:
return nil
}
}
}
InvoiceGroup - 保存按標題分組的發票資訊
import Foundation
struct InvoiceGroup {
var header: String
var invoices: [Invoice] = []
}
此函式使用https://github.com/malcommac/SwiftDate框架按其相對日期字串對所有發票進行分組
func groupInvoicesByDate(Invoices invoices: [Invoice]) -> [InvoiceGroup] {
let grouped = Dictionary(grouping: invoices) {
$0.createdAt?.toRelative()
}
let invoiceGroups = grouped.map {
InvoiceGroup(header: $0.key!, invoices: $0.value)
}
return invoiceGroups
}
要顯示標題和單元格,我這樣做:
extension HistoryViewController : UITableViewDataSource, UITableViewDelegate
{
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.invoicesGroups[section].header
}
func numberOfSections(in tableView: UITableView) -> Int {
return self.invoicesGroups.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.invoicesGroups[section].invoices.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let currentInvoice = self.invoicesGroups[indexPath.section].invoices[indexPath.row]
switch currentInvoice.getStatus() {
case .posted:
let cell = (tableView.dequeueReusableCell(withIdentifier: "HistoryItem", for: indexPath) as? HistoryViewCell)!
cell.data(item: currentInvoice, page: self, hidden: !self.isTab0(), selected: self.invoiceSelected)
cell.setCallbackListener(callback: self)
return cell
case .waiting:
let cell = (tableView.dequeueReusableCell(withIdentifier: "HistoryItem", for: indexPath) as? HistoryViewCell)!
cell.data(item: currentInvoice, page: self, hidden: !self.isTab0(), selected: self.invoiceSelected)
cell.setCallbackListener(callback: self)
return cell
case .rejected, .pending_rejection:
let cell = (tableView.dequeueReusableCell(withIdentifier: "HistoryItemReturn", for: indexPath) as? HistoryItemReturn)!
cell.data(item: currentInvoice, page: self)
return cell
case .pending_upload:
let cell = (tableView.dequeueReusableCell(withIdentifier: "HistoryItem", for: indexPath) as? HistoryViewCell)!
cell.data(item: currentInvoice, page: self)
return cell
default:
let cell = (tableView.dequeueReusableCell(withIdentifier: "HistoryItem", for: indexPath) as? HistoryViewCell)!
cell.data(item: currentInvoice, page: self)
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let currentInvoice = self.invoicesGroups[indexPath.section].invoices[indexPath.row]
switch currentInvoice.getStatus() {
case .posted:
// HistoryItem cell
return 95
case .waiting:
// HistoryItem cell
return 75
case .rejected:
// HistoryItemReturn cell
return 110
case .pending_upload:
return 75
default:
return 100
}
}
}
當我從 CoreData 獲得發票時,我將所有這些發票按 createdAt 欄位降序排列
func histories(sessionId: String, types: [InvoiceType], status : [InvoiceStatus], companyId: String, sortDate: String = "createdAt") -> [Invoice] {
var invoiceTypeList: [String] = []
var invoiceStatusList: [String] = []
for invTp in types {
invoiceTypeList.append(invTp.toString())
}
for invSt in status {
invoiceStatusList.append(invSt.toString())
}
var predicates: [NSPredicate] = []
let predicate1 = NSPredicate(format: "status IN %@", invoiceStatusList)
predicates.append(predicate1)
if !types.isEmpty {
let predicate2 = NSPredicate(format: "typeA IN %@", invoiceTypeList)
predicates.append(predicate2)
}
let predicate3 = NSPredicate(format: "sessionId = %@", sessionId as CVarArg)
predicates.append(predicate3)
let predicate4 = NSPredicate(format: "companyId = %@", companyId as CVarArg)
predicates.append(predicate4)
let compoundPredicate = NSCompoundPredicate(type: .and, subpredicates: predicates)
let sortDescriptor = NSSortDescriptor(key: sortDate, ascending: false)
let arrays = _invoiceDataRepository.getAll(predicate: compoundPredicate, sort: [sortDescriptor])
return arrays
}
但是標題在 TableView 中隨機顯示,其中包含所有發票,例如:
{
"Today": [
{
"id": 3,
"ncf": "A1",
"status": "posted"
}
],
"Yesterday": [
{
"id": 2,
"ncf": "B1",
"status": "posted"
}
],
"3 days ago": [
{
"id": 1,
"ncf": "C3",
"status": "posted"
}
]
}
如果我重新加載 TableView,訂單更改,例如:
{
"Today": [
{
"id": 3,
"ncf": "A1",
"status": "posted"
}
],
"3 days ago": [
{
"id": 1,
"ncf": "C3",
"status": "posted"
}
],
"Yesterday": [
{
"id": 2,
"ncf": "B1",
"status": "posted"
}
]
}
要么
{
"3 days ago": [
{
"id": 1,
"ncf": "C3",
"status": "posted"
}
],
"Today": [
{
"id": 3,
"ncf": "A1",
"status": "posted"
}
],
"Yesterday": [
{
"id": 2,
"ncf": "B1",
"status": "posted"
}
]
}
我不知道為什么會這樣。我需要按元素的相對日期字串降序排列的標題。
uj5u.com熱心網友回復:
你寫了:
let grouped = Dictionary(grouping: invoices) {
$0.createdAt?.toRelative()
}
let invoiceGroups = grouped.map {
InvoiceGroup(header: $0.key!, invoices: $0.value)
}
讓我們稍微修改一下以進行除錯:
let invoiceGroups = grouped.map {
print("Adding for key: \($0.key)")
return InvoiceGroup(header: $0.key!, invoices: $0.value)
}
問題是 aDictionary沒有排序,它是鍵值訪問,而不是索引值訪問。因此,不能保證要映射的第一個鍵值將是較舊的日期或最新的日期,而后面的將保持該順序。
相反,讓我們幫助您對它們進行排序。SicnetoRelative()會創建一個String, 而 "Yesterday" 和 "3 days ago" 是"難以比較的",讓我們先保留日期:
例如,讓我們使用dateTruncated(at: [.year,.month,.day])同一組中的不同時間來制作所有日期。或者你可以使用dateAtStartOf(.day). 我沒有深入圖書館,但確實本地和時區可能會導致問題,因此請檢查您的情況。
let grouped = Dictionary(grouping: invoices) {
$0.createdAt?.dateTruncated(at: [.year,.month,.day])
}
然后,讓我們將其排序為元組=
let sortedTuples = grouped.sorted(by: { $0.key < $1.key }
然后,我們可以將元組映射到您的自定義結構中:
let invoiceGroups = sortedTuples.map {
InvoiceGroupe(header: $0.key.toRelative, invoices: $0.values)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/436439.html
