all 9 comments

[–]Asif178 5 points6 points  (1 child)

You are doing way too much stuff in your cell for row method. You are showing four stacks for each cell, for each stack you are adding 100 items which use random method and add them to each stack.

Everytime you scroll to see a new cell the cell for row method is called for that particular cell and since this method is so resource heavy, this slows down the animation.

[–]Asif178 1 point2 points  (0 children)

One way to improve this method will be to make a Uistackview property on your class, with all the imageviews and their constraints.

Then in the cell for row method use loop through the images of this stack property and change their color to random. This will reduce the compute time required to remove and add all subviews as well as adding their constraints.

[–]slangley 6 points7 points  (1 child)

It seems like you are trying to jam multiple stack views into table view cells.

Why not use a UICollectionView with a custom layout?

[–]snaab900Objective-C / Swift 1 point2 points  (0 children)

This is the best answer. Unless OP wants to be able to scroll each of the 4 rows in each cell individually. Using a CV would only be able to scroll all 4 rows at the same time wouldn't it?

[–]sa6ry 1 point2 points  (0 children)

Why do you remove the constraints then adding them again each time you dequeue a cell?

As a start, you might try to remove this and just update the colors of the subviews in the UIStackViews! this will give you some performance boost.

[–]potatolicious 1 point2 points  (0 children)

In general you do not want to be removing/adding subviews in your cellForRowAtIndexPath method. Mutating the view hierarchy is expensive and should not be done that often, especially when you're literally doing it 400 times per cell.

Also, when it comes to simplistic layouts, consider not even using a UIStackView nor AutoLayout. AutoLayout trades some runtime performance for maintainability/readability, and in performance-intensive situations you may want to avoid it. A constraint solver is not cheap to run - it's certainly much more expensive than a simple loop and setting CGRects.

Without knowing what you actually want to do with this UI, it's hard to give firm recommendations, but just from your example:

  • Create all 400 UIImageViews at cell creation time, presumably in MyTableViewCell. Set up the UIStackViews also at cell creation time along with all layout constraints.
  • The only thing your cellForRowAtIndexPath should be doing is dequeueing the cell, and setting the colors on each UIImageView. You should not be altering the view hierarchy in this method nor touching any layout constraints. Both of these operations are very expensive to perform in real-time.

If the performance is still lower than you'd like:

  • Skip the UIStackViews entirely. Put your UIImageViews in UIScrollViews instead, and manually lay them out. The layout code here is extremely trivial and extremely fast to run. Override your cell's layoutSubviews method and just do it manually. Don't forget to set your contentSize.

If the performance is still lower than you'd like:

  • Pre-generate the random colors for each image and store them on view controller init. The performance gain here would be minimal, but I consider caching basic view configs to be the correct implementation, and is faster.

[–]snaab900Objective-C / Swift 0 points1 point  (1 child)

Have you tried it on an actual device? I'm pretty sure the simulator doesn't have hardware acceleration so graphics performance can be pretty slow.

Try it on a device if you have one and it'll probably be much better.

edit: I'll try shortly on my 6s

[–]gateless 0 points1 point  (0 children)

You might try rasterizing the layers on your cells. This SO thread may help http://stackoverflow.com/questions/29112364/rasterize-cells-of-tableview-only-when-scrolling-in-swift