Mat0
Mat0

Reputation: 1195

TableView cells with collectionView performance issue

I have the following layout:enter image description here When scrolling the tableView fps drops to around 25 and it becomes very jittering.

I think it's my implementation of the collectionView since a lot of operations are performed in cellForIndexAtPath. But I can't see what can be optimized?

extension MyTableViewController: UICollectionViewDelegate, UICollectionViewDataSource {

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
    // No sections are longer than 99
    if(collectionView.tag < 100)
    {
        let code = codes0[collectionView.tag].objectForKey("code") as! String

        return code.componentsSeparatedByString(",").count
    }
    else if(collectionView.tag < 200)
    {
        let code = codes1[collectionView.tag-100].objectForKey("code") as! String

        return code.componentsSeparatedByString(",").count
    }
    else
    {
        let code = codes2[collectionView.tag-200].objectForKey("code") as! String

        return code.componentsSeparatedByString(",").count
    }
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("code", forIndexPath: indexPath) as! ImageCodeCollectionViewCell

    // Read that this should help for GPU
    cell.layer.shouldRasterize = true
    cell.layer.rasterizationScale = UIScreen.mainScreen().scale

    var codeLength:String! = ""

    if(collectionView.tag < 100)
    {
        codeLength = self.codes0[collectionView.tag].objectForKey("code") as! String
    }
    else if(collectionView.tag < 200)
    {
        codeLength = self.codes1[collectionView.tag-100].objectForKey("code") as! String
    }
    else
    {
        codeLength = self.codes2[collectionView.tag-200].objectForKey("code") as! String
    }

    let cLength = codeLength.componentsSeparatedByString(",")

    if(indexPath.row <= cLength.count)
    {
        cell.imageCode.image = UIImage(named: cLength[indexPath.row])
    }

    return cell
}

My tableView looks like:

Here's the collectionView data source and delegate set

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCellWithIdentifier("cheat") as! CodeTableViewCell

    cell.layer.shouldRasterize = true
    cell.layer.rasterizationScale = UIScreen.mainScreen().scale

    cell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row, forSection: indexPath.section)

    return cell
}

func tableView(tableView: UITableView, willDisplayCell cell: CodeTableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
{
    switch indexPath.section
    {
    case 2:
        cell.name = codes2[indexPath.row].objectForKey("name") as! String

        cell.descript = ((codes2[indexPath.row].objectForKey("description") as! String).isEmpty ? "-" : codes2[indexPath.row].objectForKey("description") as! String)

    case 1:
        cell.name = codes1[indexPath.row].objectForKey("name") as! String

        cell.descript = ((codes1[indexPath.row].objectForKey("description") as! String).isEmpty ? "-" : codes1[indexPath.row].objectForKey("description") as! String)

    default:
        cell.name = codes0[indexPath.row].objectForKey("name") as! String

        cell.descript = ((codes0[indexPath.row].objectForKey("description") as! String).isEmpty ? "-" : codes0[indexPath.row].objectForKey("description") as! String)
    }
}

Upvotes: 1

Views: 1350

Answers (1)

Aerows
Aerows

Reputation: 760

From looking briefly at your code, it seams like you would be fine with only an UICollectionView setup that makes use of UICollectionReusableView as headers. That way all the collectionViews would reuse the same cells and you don't have to layout the collectionViews each time a UITableViewCell becomes visible.

Interface Builder setup

Also you might consider storing the results of operations such as code.componentsSeparatedByString(",").count in separate variables, and only calculate it once your data is changed.

Upvotes: 1

Related Questions