Я создаю SalesViewController
для своего приложения, и оно состоит из TableView
, показывающего все элементы, найденные в диапазоне дат.Item
является дочерним для Order
и имеет атрибуты category
, date
, itemId
, itemName
, price
все String
.Мне наконец удалось отобразить результат правильного деления itemFetchResultController
на разделы, так как я ошибся sortDescriptor
.При настройке itemFetchResultController
я хочу использовать свойство category
из выбранных Item
сущностей, чтобы заголовок раздела отображался в заполненном TableView
.Моя цель, тесто, я не уверен, что было бы возможно или как этого достичь, чтобы иметь только 1 строку на itemName
в своем разделе, но знаю, что многие из них были найдены в выборке, и использую ее для отображения проданной стоимости.,Это первый раз, когда я использую sections
, и это меня немного смущает.Я пытаюсь следовать примеру кода документации Apple, который дает мне пару ошибок в методах источника данных tableView, как вы можете видеть по закомментированному коду.Все остальные сообщения, которые я нашел здесь о переполнении стека, очень старые и имеют цель c, поэтому я не нахожу ответы на свои сомнения.Пока что TableView
заполняется правильно, но заголовок первого раздела не перемещается при прокрутке.
Есть идеи, что вызвало это?Как всегда большое спасибо.
Вот код, который я использую для itemFetchResultController
:
lazy var itemFetchedResultController: NSFetchedResultsController<Item> = {
// first sortDescriptor filters the date range: possibly change date from String to dates in both function and CoreData and use "(date >= %@) AND (date <= %@)" instead of "BEGINSWITH" in predicate
let itemFetchRequest = NSFetchRequest<Item>(entityName: "Item")
itemFetchRequest.sortDescriptors = [NSSortDescriptor(key: "category", ascending: true)]
itemFetchRequest.predicate = NSPredicate(format: "order.user.name == %@", UserDetails.fullName!)
itemFetchRequest.predicate = NSPredicate(format: "date BEGINSWITH %@", dateToFetch)
let itemFetchedResultController = NSFetchedResultsController(fetchRequest: itemFetchRequest, managedObjectContext: context, sectionNameKeyPath: "category", cacheName: nil)
return itemFetchedResultController
}()
TableView
источник данных:
func numberOfSections(in tableView: UITableView) -> Int {
// apple doc : trhrows an error : Initializer for conditional binding must have Optional type, not 'NSFetchedResultsController<Item>'
// if let frc = itemFetchedResultController {
// return frc.sections!.count
// }
// return 0
return itemFetchedResultController.sections!.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let sections = self.itemFetchedResultController.sections else {
print(" Error :no sections in fetchedResultController" )
return 0
}
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "statisticsCell", for: indexPath) as! StatisticsTableViewCell
cell.idInfoLabel.text = itemFetchedResultController.object(at: indexPath).itemId!
cell.nameInfoLabel.text = itemFetchedResultController.object(at: indexPath).itemName!
let item = itemFetchedResultController.object(at: indexPath).itemName!
let productRequest: NSFetchRequest<Product> = Product.fetchRequest()
productRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
productRequest.predicate = NSPredicate(format: "name == %@", item)
productRequest.fetchLimit = 1
do {
let fetch = try context.fetch(productRequest)
cell.productImageView.image = UIImage(data: (fetch[0].productImage! as Data))
cell.minimumStockInfoLabel.text = fetch[0].minimumStock
cell.soldQuantityInfoLabel.text = fetch[0].soldQuantity
} catch {
print("Error in fetching product for cell: \(error)")
}
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
// guard let sections = self.itemFetchedResultController.sections else {
// print(" Error : no sections in itemsFetchedResultController " )
// return "empty"
// }
// let sectionInfo = sections[section]
// return sectionInfo.name
guard let sectionInfo = itemFetchedResultController.sections?[section] else {
return nil
}
return sectionInfo.name
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
// if let sectionIndexTitles: FetchedResultController.sectionIndexTitles = self.itemFetchedResultController.sectionIndexTitles {
// print(" Error : no sections in itemsFetchedResultController " )
// return [""]
// }
return itemFetchedResultController.sectionIndexTitles
}
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
// apple doc : trhrows an error : Initializer for conditional binding must have Optional type, not 'Int'
// guard let result = itemFetchedResultController.section(forSectionIndexTitle: title, at: index) else {
// fatalError("Unable to locate section for \(title) at index: \(index)")
// }
// return result
let result = itemFetchedResultController.section(forSectionIndexTitle: title, at: index)
return result
}