Collection-View-in-a-Table-View-Cell icon indicating copy to clipboard operation
Collection-View-in-a-Table-View-Cell copied to clipboard

CollectionView seems to make tableView jittery/laggy

Open mreilly4 opened this issue 9 years ago • 21 comments

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

Thanks!

mreilly4 avatar Aug 06 '16 14:08 mreilly4

What do you mean? Can you describe the issue?

ashfurrow avatar Aug 06 '16 14:08 ashfurrow

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 [email protected] 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 .

mreilly4 avatar Aug 06 '16 14:08 mreilly4

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
}

ashfurrow avatar Aug 06 '16 14:08 ashfurrow

That gives an error for some reason...

On Saturday, August 6, 2016, Ash Furrow [email protected] 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 avatar Aug 06 '16 15:08 mreilly4

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 [email protected] wrote:

That gives an error for some reason...

On Saturday, August 6, 2016, Ash Furrow [email protected] 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 avatar Aug 06 '16 15:08 mreilly4

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?

ashfurrow avatar Aug 06 '16 15:08 ashfurrow

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 [email protected] 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 avatar Aug 06 '16 15:08 mreilly4

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 [email protected] 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 [email protected] 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 avatar Aug 06 '16 22:08 mreilly4

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 [email protected] 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 [email protected] 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 [email protected] 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 avatar Aug 06 '16 23:08 mreilly4

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...

ashfurrow avatar Aug 08 '16 14:08 ashfurrow

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 [email protected] 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 .

mreilly4 avatar Aug 08 '16 14:08 mreilly4

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

ashfurrow avatar Aug 08 '16 15:08 ashfurrow

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

Auxton avatar Feb 06 '17 21:02 Auxton

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:

ashfurrow avatar Feb 08 '17 15:02 ashfurrow

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 [email protected] 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 .

mreilly4 avatar Feb 08 '17 15:02 mreilly4

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];

  • (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ [self.visibleCollectionViews makeObjectsPerformSelector:@selector(_updateContentOffset:) withObject:nil]; }

//CollectionView.m

  • (void)scrollViewDidScroll:(UIScrollView *)scrollView{ if (hasBeganScrolling) return;

    sharedData.updatedContentOffset = scrollView.contentOffset; }

this triggers the KVO in the tableView subclass where I set the contentOffset of all visible collectionsViews.

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

Auxton avatar Feb 08 '17 16:02 Auxton

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

dani2906 avatar Jul 25 '17 22:07 dani2906

  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

Auxton avatar Jul 26 '17 06:07 Auxton

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

dani2906 avatar Jul 26 '17 12:07 dani2906

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, .....}

Auxton avatar Jul 26 '17 12:07 Auxton

@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.

PaulRBerg avatar Jul 28 '17 10:07 PaulRBerg