Vincenzo
Vincenzo

Reputation: 6358

First TableView section title doesn't scroll Swift 4

I'm building the SalesViewControllerfor my app and it consists of a TableView showing all items found in a date range. Itemis child of Order and it has category, date, itemId, itemName, priceattributes all String. I finally succeed in displaying the result of itemFetchResultController properly divided in sections as I had wrong sortDescriptor. In configuring itemFetchResultController I want use category property from fetched Item entities to be the section displayed title in populated TableView. My goal is, dough I'm not sure it would be possible or how to achieve it, to only have 1 row per itemName in its section but know ho many of it have been found in fetch and use it to display sold value. It's the first time I use sections and it's all a bit confusing to me. I'm trying to follow Apple documentation sample code gives me a couple of errors in tableView's data source methods as you can see by commented out code. All other posts I found here on stack overflow are very old and in objective c so I don't find answers to my doubts. So far TableViewgets populated correctly , but first section title doesn't move when scrolling.

Any Idea of what's causing this ? As always many thanks.

Here is the code I'm using for 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 data source:

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

    }

Upvotes: 1

Views: 1506

Answers (1)

Ajay saini
Ajay saini

Reputation: 2470

Set your UITableView style to grouped and your all section will scroll along with cells

enter image description here

Upvotes: 3

Related Questions