ashfurrow / Collection-View-in-a-Table-View-Cell

Sample code for my tutorial
http://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell-in-swift/
MIT License
395 stars 81 forks source link

CollectionView seems to make tableView jittery/laggy #24

Open mreilly4 opened 8 years ago

mreilly4 commented 8 years ago

Anythoughts what could be make it smother as it reuses cells?

Thanks!

ashfurrow commented 8 years ago

What do you mean? Can you describe the issue?

mreilly4 commented 8 years ago

When I scroll the tableView Vertically it is jumpy. Skips and freezes intermittently.

Great tutorial by the way. Easy to follow and it works fine just feel like there is something I can do to make it smoother.

Thanks a ton for the response!

Mike

On Sat, Aug 6, 2016 at 9:42 AM, Ash Furrow notifications@github.com wrote:

What do you mean? Can you describe the issue?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/issues/24#issuecomment-238026580, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmm9rDJsXbdWyDoh56zV8xSYUt9iIPYks5qdJ1IgaJpZM4JeSjq .

ashfurrow commented 8 years ago

Thanks :bow:

Dropping frames isn't good, hmm. I would need to profile using the Time Profile in Instruments.app to make sure, but this is the code that gets called for each cell, maybe there's something there we can optimize.

For example, the delegate and datasource are always the same, maybe re-setting them does something expensive?

if collectionView.delegate != dataSourceDelegate {
    collectionView.delegate = dataSourceDelegate
    collectionView.dataSource = dataSourceDelegate
}
mreilly4 commented 8 years ago

That gives an error for some reason...

On Saturday, August 6, 2016, Ash Furrow notifications@github.com wrote:

Thanks 🙇

Dropping frames isn't good, hmm. I would need to profile using the Time Profile in Instruments.app to make sure, but this https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/blob/ec5af131532c833557c128e2e0643de478e0b573/Table%20View%20in%20a%20Collection%20View/TableViewCell.swift#L13-L17 is the code that gets called for each cell, maybe there's something there we can optimize.

For example, the delegate and datasource are always the same, maybe re-setting them does something expensive?

if collectionView.delegate != dataSourceDelegate { collectionView.delegate = dataSourceDelegate collectionView.dataSource = dataSourceDelegate }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/issues/24#issuecomment-238026954, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmm9njHulKMRUBB_gdrxGtrAeWooQzaks5qdJ74gaJpZM4JeSjq .

mreilly4 commented 8 years ago

I am loading thumbnails to a UIImageView in each cell. Might be that but I previously just loaded them to static UIImageViews in a tableViewCell and there were no issues with performance there.

Thanks for your help.

On Sat, Aug 6, 2016 at 10:00 AM, Michael Reilly mreilly4@alumni.nd.edu wrote:

That gives an error for some reason...

On Saturday, August 6, 2016, Ash Furrow notifications@github.com wrote:

Thanks 🙇

Dropping frames isn't good, hmm. I would need to profile using the Time Profile in Instruments.app to make sure, but this https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/blob/ec5af131532c833557c128e2e0643de478e0b573/Table%20View%20in%20a%20Collection%20View/TableViewCell.swift#L13-L17 is the code that gets called for each cell, maybe there's something there we can optimize.

For example, the delegate and datasource are always the same, maybe re-setting them does something expensive?

if collectionView.delegate != dataSourceDelegate { collectionView.delegate = dataSourceDelegate collectionView.dataSource = dataSourceDelegate }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/issues/24#issuecomment-238026954, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmm9njHulKMRUBB_gdrxGtrAeWooQzaks5qdJ74gaJpZM4JeSjq .

ashfurrow commented 8 years ago

Image views can be tricky, because they use UIImage which does a lot of work under the hood. For example, displaying a JPEG requires it to be decompressed first. That's usually fast enough that it doesn't matter, but showing lots of images or showing large images (or both!) can cause performance issues.

What's the error you're getting?

mreilly4 commented 8 years ago

I set my app up to load images from a cache. If the cache doesnt exists it loads them asynchroniously. Then updates the collectionViewCell. It shouldn't make the tableView lag or jump while scrolling...

I register my CollectionCell XIB in my custom tableViewCell file 'awakeFromNib()' function.

Is this expensive?

I also have to fetch from core data each time a tableViewcell is presented to find out how many collectionView Items i have. See below. Is anything here expensive?

extension NotesTableViewController: UICollectionViewDelegate, UICollectionViewDataSource {

func collectionView(collectionView: UICollectionView,

                    numberOfItemsInSection section: Int) -> Int {

    var photoFilteredIndexRow = Int()

    if (searchController.active && searchController.searchBar.text != "")

|| searchController.searchBar.text != "" {

        photoFilteredIndexRow = filteredNotes[collectionView.tag]

    } else {

        photoFilteredIndexRow = collectionView.tag

    }

// first get the photos for this cell

    let noteCollection = notesFRC?.objectAtIndexPath(NSIndexPath(forRow:

collectionView.tag, inSection: 0)) as! Notes

    setupPhotosFetchedResultsController(noteCollection)

    print("We got this many in collection view for row \(collectionView.

tag) : ((photosFRC?.fetchedObjects?.count)!)")

    return (photosFRC?.fetchedObjects?.count)!

}

func collectionView(collectionView: UICollectionView,

                    cellForItemAtIndexPath indexPath: NSIndexPath) ->

UICollectionViewCell {

    var photoFilteredIndexRow = Int()

    if (searchController.active && searchController.searchBar.text != "")

|| searchController.searchBar.text != "" {

        photoFilteredIndexRow = filteredNotes[collectionView.tag]

    } else {

        photoFilteredIndexRow = collectionView.tag

    }

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("\(

collectionCellIdentifier)", forIndexPath: indexPath) as! CollectionCell

    configureTextForCollectionCell(cell, withIndexPath: indexPath,

collectionViewTag: photoFilteredIndexRow)

    return cell

}

func configureTextForCollectionCell(cell: CollectionCell, withIndexPath

indexPath: NSIndexPath, collectionViewTag: Int) {

    let noteCollection = notesFRC?.objectAtIndexPath(NSIndexPath(forRow:

collectionViewTag, inSection: 0)) as! Notes

    setupPhotosFetchedResultsController(noteCollection)

    if let photoItem = photosFRC?.objectAtIndexPath(indexPath) as?

Photos {

        if let image = imageCache["\(photoItem.content)"] {

                            print("THERE IS A CACHE FOR COLLECTION!!")

            cell.photoImage.image = image

        } else {

            urlString = photoItem.content as String

            imgURL = NSURL(string: urlString)

            loadImage(imgURL!, urlString: urlString, indexPath:

indexPath, cell: cell)

        }

    }

}

func loadImage(imgURL: NSURL, urlString: String, indexPath: NSIndexPath,

cell: CollectionCell) {

    print("loading image!!!")

    let request: NSURLRequest = NSURLRequest(URL: imgURL)

    let mainQueue = NSOperationQueue.mainQueue()

    NSURLConnection.sendAsynchronousRequest(request, queue: mainQueue,

completionHandler: { (response, data, error) -> Void in

        if error == nil {

            // Convert the downloaded data in to a UIImage object

            let image = UIImage(data: data!)

            // Store the image in to our cache

            self.imageCache[urlString] = image

            // Update the cell

            dispatch_async(dispatch_get_main_queue(), {

                if (self.searchController.active && self.

searchController.searchBar.text != "") || self.searchController.searchBar. text != "" {

                    for i in 0 ..< self.filteredNotes.count {

                        if self.filteredNotes[i] == indexPath.row {

                            self.filteredIndexPath = NSIndexPath(forRow:

self.filteredNotes[indexPath.row], inSection: 0)

                        }

                    }

                } else {

                    self.filteredIndexPath = indexPath

                }

                if let cellToUpdate = cell as? CollectionCell {

                    cellToUpdate.photoImage.image = image

                }

            })

        }

    })

}

}

On Sat, Aug 6, 2016 at 10:23 AM, Ash Furrow notifications@github.com wrote:

Image views can be tricky, because they use UIImage which does a lot of work under the hood. For example, displaying a JPEG requires it to be decompressed first. That's usually fast enough that it doesn't matter, but showing lots of images or showing large images (or both!) can cause performance issues.

What's the error you're getting?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/issues/24#issuecomment-238028552, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmm9p-tTgptAbnUmvH7Sy90IK_pE4y-ks5qdKbXgaJpZM4JeSjq .

mreilly4 commented 8 years ago

Ash,

It does seem to be the

setCollectionViewDataSourceDelegate

function that is slowing everything down. Do you know where we might be able to call this in the tableView VC so it only happens once?

Thanks!

Mike

On Sat, Aug 6, 2016 at 10:30 AM, Michael Reilly mreilly4@alumni.nd.edu wrote:

I set my app up to load images from a cache. If the cache doesnt exists it loads them asynchroniously. Then updates the collectionViewCell. It shouldn't make the tableView lag or jump while scrolling...

I register my CollectionCell XIB in my custom tableViewCell file 'awakeFromNib()' function.

Is this expensive?

I also have to fetch from core data each time a tableViewcell is presented to find out how many collectionView Items i have. See below. Is anything here expensive?

extension NotesTableViewController: UICollectionViewDelegate, UICollectionViewDataSource {

func collectionView(collectionView: UICollectionView,

                    numberOfItemsInSection section: Int) -> Int {

    var photoFilteredIndexRow = Int()

    if (searchController.active && searchController.searchBar.text !=

"") || searchController.searchBar.text != "" {

        photoFilteredIndexRow = filteredNotes[collectionView.tag]

    } else {

        photoFilteredIndexRow = collectionView.tag

    }

// first get the photos for this cell

    let noteCollection = notesFRC?.objectAtIndexPath(NSIndexPath(forRow:

collectionView.tag, inSection: 0)) as! Notes

    setupPhotosFetchedResultsController(noteCollection)

    print("We got this many in collection view for row \(

collectionView.tag) : ((photosFRC?.fetchedObjects?.count)!)")

    return (photosFRC?.fetchedObjects?.count)!

}

func collectionView(collectionView: UICollectionView,

                    cellForItemAtIndexPath indexPath: NSIndexPath) ->

UICollectionViewCell {

    var photoFilteredIndexRow = Int()

    if (searchController.active && searchController.searchBar.text !=

"") || searchController.searchBar.text != "" {

        photoFilteredIndexRow = filteredNotes[collectionView.tag]

    } else {

        photoFilteredIndexRow = collectionView.tag

    }

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("

(collectionCellIdentifier)", forIndexPath: indexPath) as! CollectionCell

    configureTextForCollectionCell(cell, withIndexPath: indexPath,

collectionViewTag: photoFilteredIndexRow)

    return cell

}

func configureTextForCollectionCell(cell: CollectionCell,

withIndexPath indexPath: NSIndexPath, collectionViewTag: Int) {

    let noteCollection = notesFRC?.objectAtIndexPath(NSIndexPath(forRow:

collectionViewTag, inSection: 0)) as! Notes

    setupPhotosFetchedResultsController(noteCollection)

    if let photoItem = photosFRC?.objectAtIndexPath(indexPath) as?

Photos {

        if let image = imageCache["\(photoItem.content)"] {

                            print("THERE IS A CACHE FOR COLLECTION!!")

            cell.photoImage.image = image

        } else {

            urlString = photoItem.content as String

            imgURL = NSURL(string: urlString)

            loadImage(imgURL!, urlString: urlString, indexPath:

indexPath, cell: cell)

        }

    }

}

func loadImage(imgURL: NSURL, urlString: String, indexPath:

NSIndexPath, cell: CollectionCell) {

    print("loading image!!!")

    let request: NSURLRequest = NSURLRequest(URL: imgURL)

    let mainQueue = NSOperationQueue.mainQueue()

    NSURLConnection.sendAsynchronousRequest(request, queue:

mainQueue, completionHandler: { (response, data, error) -> Void in

        if error == nil {

            // Convert the downloaded data in to a UIImage object

            let image = UIImage(data: data!)

            // Store the image in to our cache

            self.imageCache[urlString] = image

            // Update the cell

            dispatch_async(dispatch_get_main_queue(), {

                if (self.searchController.active && self.

searchController.searchBar.text != "") || self.searchController.searchBar. text != "" {

                    for i in 0 ..< self.filteredNotes.count {

                        if self.filteredNotes[i] == indexPath.row {

                            self.filteredIndexPath = NSIndexPath(forRow:

self.filteredNotes[indexPath.row], inSection: 0)

                        }

                    }

                } else {

                    self.filteredIndexPath = indexPath

                }

                if let cellToUpdate = cell as? CollectionCell {

                    cellToUpdate.photoImage.image = image

                }

            })

        }

    })

}

}

On Sat, Aug 6, 2016 at 10:23 AM, Ash Furrow notifications@github.com wrote:

Image views can be tricky, because they use UIImage which does a lot of work under the hood. For example, displaying a JPEG requires it to be decompressed first. That's usually fast enough that it doesn't matter, but showing lots of images or showing large images (or both!) can cause performance issues.

What's the error you're getting?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/issues/24#issuecomment-238028552, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmm9p-tTgptAbnUmvH7Sy90IK_pE4y-ks5qdKbXgaJpZM4JeSjq .

mreilly4 commented 8 years ago

Actually, after messing with it more it seems the below code is holding up the show...

override func tableView(tableView: UITableView,

                        willDisplayCell cell: UITableViewCell,

                                        forRowAtIndexPath indexPath:

NSIndexPath) {

    guard let cell =

tableView.dequeueReusableCellWithIdentifier(notePhotoCollectionCellIdentifier) as? NotePhotoCollectionCell else { return }

    print("in willDisplayCell")

    cell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0

}

override func tableView(tableView: UITableView,

                        didEndDisplayingCell cell: UITableViewCell,

                                             forRowAtIndexPath

indexPath: NSIndexPath) {

    guard let cell =

tableView.dequeueReusableCellWithIdentifier(notePhotoCollectionCellIdentifier) as? NotePhotoCollectionCell else { return }

    storedOffsets[indexPath.row] = cell.collectionViewOffset

    }

}

The tableView flies smoothly without this code. Only thing is the photos sorta get jumbled up and the collectionView show incorrect number of cells etc.

Any ideas?

Mike

On Sat, Aug 6, 2016 at 5:46 PM, Michael Reilly mreilly4@alumni.nd.edu wrote:

Ash,

It does seem to be the

setCollectionViewDataSourceDelegate

function that is slowing everything down. Do you know where we might be able to call this in the tableView VC so it only happens once?

Thanks!

Mike

On Sat, Aug 6, 2016 at 10:30 AM, Michael Reilly mreilly4@alumni.nd.edu wrote:

I set my app up to load images from a cache. If the cache doesnt exists it loads them asynchroniously. Then updates the collectionViewCell. It shouldn't make the tableView lag or jump while scrolling...

I register my CollectionCell XIB in my custom tableViewCell file 'awakeFromNib()' function.

Is this expensive?

I also have to fetch from core data each time a tableViewcell is presented to find out how many collectionView Items i have. See below. Is anything here expensive?

extension NotesTableViewController: UICollectionViewDelegate, UICollectionViewDataSource {

func collectionView(collectionView: UICollectionView,

                    numberOfItemsInSection section: Int) -> Int {

    var photoFilteredIndexRow = Int()

    if (searchController.active && searchController.searchBar.text

!= "") || searchController.searchBar.text != "" {

        photoFilteredIndexRow = filteredNotes[collectionView.tag]

    } else {

        photoFilteredIndexRow = collectionView.tag

    }

// first get the photos for this cell

    let noteCollection = notesFRC?.objectAtIndexPath(NSIndexPath(forRow:

collectionView.tag, inSection: 0)) as! Notes

    setupPhotosFetchedResultsController(noteCollection)

    print("We got this many in collection view for row \(

collectionView.tag) : ((photosFRC?.fetchedObjects?.count)!)")

    return (photosFRC?.fetchedObjects?.count)!

}

func collectionView(collectionView: UICollectionView,

                    cellForItemAtIndexPath indexPath: NSIndexPath)

-> UICollectionViewCell {

    var photoFilteredIndexRow = Int()

    if (searchController.active && searchController.searchBar.text

!= "") || searchController.searchBar.text != "" {

        photoFilteredIndexRow = filteredNotes[collectionView.tag]

    } else {

        photoFilteredIndexRow = collectionView.tag

    }

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(

"(collectionCellIdentifier)", forIndexPath: indexPath) as! CollectionCell

    configureTextForCollectionCell(cell, withIndexPath: indexPath,

collectionViewTag: photoFilteredIndexRow)

    return cell

}

func configureTextForCollectionCell(cell: CollectionCell,

withIndexPath indexPath: NSIndexPath, collectionViewTag: Int) {

    let noteCollection = notesFRC?.objectAtIndexPath(NSIndexPath(forRow:

collectionViewTag, inSection: 0)) as! Notes

    setupPhotosFetchedResultsController(noteCollection)

    if let photoItem = photosFRC?.objectAtIndexPath(indexPath) as?

Photos {

        if let image = imageCache["\(photoItem.content)"] {

                            print("THERE IS A CACHE FOR COLLECTION!!"

)

            cell.photoImage.image = image

        } else {

            urlString = photoItem.content as String

            imgURL = NSURL(string: urlString)

            loadImage(imgURL!, urlString: urlString, indexPath:

indexPath, cell: cell)

        }

    }

}

func loadImage(imgURL: NSURL, urlString: String, indexPath:

NSIndexPath, cell: CollectionCell) {

    print("loading image!!!")

    let request: NSURLRequest = NSURLRequest(URL: imgURL)

    let mainQueue = NSOperationQueue.mainQueue()

    NSURLConnection.sendAsynchronousRequest(request, queue:

mainQueue, completionHandler: { (response, data, error) -> Void in

        if error == nil {

            // Convert the downloaded data in to a UIImage object

            let image = UIImage(data: data!)

            // Store the image in to our cache

            self.imageCache[urlString] = image

            // Update the cell

            dispatch_async(dispatch_get_main_queue(), {

                if (self.searchController.active && self.

searchController.searchBar.text != "") || self.searchController.searchBar .text != "" {

                    for i in 0 ..< self.filteredNotes.count {

                        if self.filteredNotes[i] == indexPath.row {

                            self.filteredIndexPath = NSIndexPath(forRow:

self.filteredNotes[indexPath.row], inSection: 0)

                        }

                    }

                } else {

                    self.filteredIndexPath = indexPath

                }

                if let cellToUpdate = cell as? CollectionCell {

                    cellToUpdate.photoImage.image = image

                }

            })

        }

    })

}

}

On Sat, Aug 6, 2016 at 10:23 AM, Ash Furrow notifications@github.com wrote:

Image views can be tricky, because they use UIImage which does a lot of work under the hood. For example, displaying a JPEG requires it to be decompressed first. That's usually fast enough that it doesn't matter, but showing lots of images or showing large images (or both!) can cause performance issues.

What's the error you're getting?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/issues/24#issuecomment-238028552, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmm9p-tTgptAbnUmvH7Sy90IK_pE4y-ks5qdKbXgaJpZM4JeSjq .

ashfurrow commented 8 years ago

Strange! I'd try commenting only one or the other out, to see if it's setting or getting that's causing the issue. It's not obvious to me why that would be slowing the performance down...

mreilly4 commented 8 years ago

Ash,

So it appears as though setting th offset causes the collectionView in each cell to reloadData. reloadData is also being called. I am trying to find a way to do this as early as possible in the cell's reuse in order to have it reloaded before it appears and hopefully not cause the skipping effect when the cell appears in the TableView. If you have any ideas that would be great.

Hope you had a great weekend.

Thanks,

Mike

On Mon, Aug 8, 2016 at 9:31 AM, Ash Furrow notifications@github.com wrote:

Strange! I'd try commenting only one or the other out, to see if it's setting or getting that's causing the issue. It's not obvious to me why that would be slowing the performance down...

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/issues/24#issuecomment-238255762, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmm9nVngWVRG1MSfQa1QoLVN7RyV0MJks5qdz2qgaJpZM4JeSjq .

ashfurrow commented 8 years ago

Ah, good thinking! Good luck, let me know if I can help :bow:

Auxton commented 7 years ago

Hello Ashfurrow, I seem to be having the same problem as mreily4. I have tried a number of debugging and can't seem to find and clues why there are jitters. Have you find any reason why?? Or any way to improve performance

ashfurrow commented 7 years ago

Not sure of the cause, sorry. I don't have a tonne of time to work on this but if you have suggestions or ideas, please follow up :bow:

mreilly4 commented 7 years ago

For me it was constantly fetching from Core Data too. So what I did was cache all my objects and images after the first load. Then checking the cache before initiating a fetch from Core Data each time I loaded cells.

Mike

On Wed, Feb 8, 2017 at 9:36 AM, Ash Furrow notifications@github.com wrote:

Not sure of the cause, sorry. I don't have a tonne of time to work on this but if you have suggestions or ideas, please follow up 🙇

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell/issues/24#issuecomment-278362448, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmm9p6ZqRWYfgfkLOEXXetHa13GLC5mks5raeD1gaJpZM4JeSjq .

Auxton commented 7 years ago

I noticed the jitter occurs when a new cell is inserted on the fly whilst scrolling the tableview and as we don't have control of when apple creates/removes a cell this happens quite often.

Currently I have a property (CGPoint *updatedContentOffset) which I observer in my tableView subclass and then in my collectionview subclass inside scrollViewDidScroll delegate I set this property with the latest contentoffset of the scrolling collectionview;

//TableView.m [sharedData addObserver:self forKeyPath:NSStringFromSelector(@selector(updatedContentOffset)) options:NSKeyValueObservingOptionNew context:nil];

//CollectionView.m

This has seemed to reduce the jitter quite significantly, however on first scroll I get the slightest of glitches which goes away on subsequent scrolls.

I believe that might be tableView trying to build up the suitable number if cells for the tableView height.

@mreily4 I cannot cache my data as it sensitive data and changes quite rapidly but I do hold the data in memory (i.e. BST and array)

If you do come across and better solution than mine please update. Thanks again

dani2906 commented 7 years ago

Anyone came up with a solution? Having same issue. vertical scroll has lag. Thanks

Auxton commented 7 years ago
  1. Instead of setting the contentOffset, try setting the bounds, (e.g. if current offset is 5349, the bounds = (CGRect}{{5349, y}, size}).
  2. In collectionview cell, move all heavy computation to background thread, I noticed it slowed things down. An approach I took was creating an image in the background thread (with relevant data) then add the image as a subview of the cell (on main thread).
  3. In collectionview willDisplayCell: check if the collectionview contentOffset is same as the reference offset, if not set it. most times in catching up on contentoffset causes jitter.
  4. Uses reusable tableviewcells and collectionViewCells, if cells are created for every scroll, this causes jitter

I have managed to get 56 fps on a grid design using these pointers; however as scenarios differ, you bottleneck/issue might not be solved with these so ill suggest profiling your app whilst making changes

dani2906 commented 7 years ago

not sure I understood the first argument. Can you explain?

Auxton commented 7 years ago

In my case I was using a collectionview subclass and observing the contentoffset of the scrolling collectionview and setting other collectionviews accordingly. I noticed that setting the contentoffset of other collectionviews caused jitter so I set their bounds

Instead of: otherCollectionView.contentOffset = scrollingCollectionView.contentOffset

You do: otherCollectiinView.bounds = (CGRect){scrollingCollectionView.contentOffset, .....}

PaulRBerg commented 7 years ago

@Auxton great suggestions.

In my case, your tips were not enough. The lag was caused by having cornerRadius implemented in the storyboard. Core Animation was redrawing the corners on every call of cellFoRowAtIndexPath. I've made the views in Photoshop and added them as image views and everything works perfect now.