https://medium.com/ios-os-x-development/perfect-smooth-scrolling-in-uitableviews-fd609d5275a5

 

UIKit will be covered at the end.

Built-In Tools

 

I really believe that most people reading this story know about this, but some people, even after using these tools, are not using it in the right way.


reused instances.

described in documentation.

reused cell instance as quickly as possible.

bounds.


The second one is not as difficult to understand, but there’s one thing which should be explained.

very easily.

contentOffset and many others for displaying correct rect to user.

UITableViewdoesn’t hold all cell instances simultaneously. Instead, only required cells are shown to user.

all cell heights.

very fast.

huge mistakes by laying out initialized instance of cell with bound data to fetch their height after this. You should not use this way for calculating height of cell if you want to improve scrolling performance, ‘cause all this things are incredibly slow and 60 FPS which are standard for iOS devices will be dropped to 15–20, and your scrolling becomes laggy even with low speed.

class method for returning height based on passed width and data for displaying (it’s adapter of cell):

 

UITableView by this way:

 

Telegram’s iOS application code.

StackOverflow.

not. And more — I recommend not using even complex math calculations on your way to define further height of a cell, only addition, subtraction, multiplication and division (if possible).

AutoLayout works.

UITableView.

all of this crazy calculations.


UITableView:

  • oneinstance, no more.
  • UITableView.
  • faster. It’s routine process for engineers, but you will be awarded for your patience by increased smooth scrolling on sets of complex cells.

We need to go deeper

 

really smooth scrolling, and especially it becoming noticeable when you have task to implement complex cell with lots of gradients, views, interactive elements, some decorative elements and more.

rendering.


UIViewtransparent or not. If not — drawing system can make some optimizations when rendering this view and increase performance.

very quickly. More quickly than “usual” views.

blending. It performs with support of device GPU since exactly this hardware was developed for blending (not only blending).

As you might guess, the approach to increase performance is reduction of number of blending operations. But before reduce something you should find it. Let’s try.

Run your app on iOS Simulator, highlight item “Debug” and then pick item “Color Blended Layers”. Since this point iOS Simulator will displaying all areas into two colors: green and red.

Green places are not have a blending but red places are.

 
 

As you see, there is at least two places in cell where blending has been performed, but you can not really see difference (and this blending operation is unnecessary!).

backgroundColor to non-transparent is all that I should do for achieving this.

But sometimes we have more complicated things. Look at this: we have a gradient, but blending is absent.

 
 

CAGradientLayer to implement this, you’ll be disappointed: FPS will be reduced to 25–30 on iPhone 6 and fast scrolling will become impossible.

CAGraidentLayer.

With correct utilizing CPU & GPU resources, they are loaded evently, FPS keeps about 60. It seems like this:

 

Problems begins when device needs to perform a lot of blending operations: GPU will be fully loaded, but CPU will keeps low loading and will be useless.

Most of engineers are faced with this problem at end of summer 2010, right after releasing iPhone 4. Then Apple had presented revolutionary Retina display and… completely ordinary GPU. However, it had enough power at common, but problem described above had become more frequent.

Echoes of this decision you can see at current iPhone 4 behaviour under iOS 7 — there all applications became laggy, even most simple. Anyway, by applying all suggestions from this story you will be able to achieve 60 FPS even in this conditions, although with difficulty.

CALayers for performing some animations.

UIView by this way:

 

UITableView more smoothly.

not be loaded at 100% in many cases.

balance of loading CPU & GPU.


UITableView:

  • Instruments; gradient will be done better without blending if you can do this.
  • balance of loading CPU & GPU. You should clearly know which part of rendering must be done by GPU, and which one — by CPU for keeping balance.
  • Write specific code for specific cell types.

Pixel hunting

 

Do you know how pixels look? I mean, how look physical pixels in screen? I sure you know but I will show you:

 

Different screens are different made, but there’s one common thing. In fact, each physical pixel made by three colored subpixels: red, green and blue.

Since this fact each pixel isn’t atomic unit, although it is true for application. Or still it isn’t?

float.

subpixel rendering.

This technology does make sense when applied to specific type of content (text, for example). But it unnecessary when we drawing smooth line by design.

If all your smooth lines are rendered with subpixel rendering (which will not be visible, ‘cause your lines are smooth by design), you make iOS to do unnecessary job and you will get FPS decreasing.


How to get problems with unnecessary subpixel antialiasing? Most frequently happened cases are code-calculated views coordinates which becomes float or incorrect images assets where image sizes are not aligned to physical pixels of screen (for example, if you have image with size 60x61 for Retina display insted of 60x60).

As at previous time, before reducing something we should to find it. Run your application on iOS Simulator and pick menu item “Color Misaligned Images” at “Debug” menu.

At this time there’s two highlighted areas: magenta — areas where’s performing subpixel rendering and yellow — where’s image sizes that rendered are not aligned to area where they are.

 
 
Perfect smooth scrolling in UITableViewsPerfect smooth scrolling in UITableViews

sympathize you.

CGRectIntegral for rounding your coordinates. That’s all!


By hunting results I would like to suggest you following:

  • UIViews and many others.
  • Track your graphical resources: images must be pixel-perfect, else when they will be rendered on Retina displays, it will be doing with unnecessary antialiasing.
  • Periodically recheck your situation with this problem ‘cause it can changes very quickly.

Asynchronous UI

 

UITableView scrolling more smoothly if you know what you’re doing.

may.


Each application with medium level and above necessarily uses cells with custom media content: text, images, animations, even videos sometimes.

And all this stuff is decorated: avatars are rounded, text has a hashtags, usernames, etc.

clipsToBounds is slow, images should be loaded from network, hashtags needs to be located at string, and many others.

should performing those operations which will not allow you to returning cells quickly if performed in main thread.

UIImageView.

Display text at once, but locate hashtags in background and then refresh displayed text with attributed string.

Instruments to find them all.

Remember about need to returning cells quickly.


drawRect:.

UITableView too fast.

For example look at Facebook application which doing exactly this. For detecting this you may scroll down enough and then tap on status bar. List instantly will scrolling up, so you can clearly see that cells are not rendered at this moment. If to be more precisely — can’t get in time.

CALayers to YES.

But we can check the necessity of this actions. Run the application in iOS Simulator, select item “Color Offscreen-Rendered” at “Debug” menu. Now all areas which are rendered in background wil be highlighted in yellow.

 
 

If you enabled this mode for some layer, but it hasn’t become highlighted, then this one is not slow enough.

Instruments.


And here’s list of actions for implementation of asynchronous UI:

  • Find render bottlenecks which don’t allow you to return cells very fast.
  • Move operations to background thread and refresh displayed content on the main thread.
  • CALayers for asynchronous displaying mode (even if they are about simple text or images) — this will help you to increase FPS.

Results

 

directions where you should research your code to find all troubles with scroll performance.

principlesare never changes.

And the key to achieve perfect smooth scrolling is the very specific code, which allows you to use all available power of iOS devices to make really smooth applications.


Subscribe, recommend the story, discuss and enjoy! Thanks for your time.

相关文章:

  • 2021-04-09
  • 2021-08-20
  • 2021-11-06
  • 2022-02-11
  • 2021-06-11
  • 2022-01-18
  • 2021-05-29
猜你喜欢
  • 2021-09-01
  • 2021-10-30
  • 2022-12-23
  • 2022-01-02
  • 2021-08-25
  • 2022-12-23
  • 2021-06-27
相关资源
相似解决方案