Working with Scrolling Content

Pixel-based scrolling tables and scrolling layers provide the ability to scroll content in a smooth and uniform fashion. Configuring tables for scrolling is covered in the chapter Creating Lists and Tables. Scrolling layers are based entirely on the bounds of their child group and control content, and require selecting Enable scrolling, within the Properties View.

Properties for scrolling

When scrolling is enabled, the object that is being scrolled, be it a layer or a table, is moved as if it were positioned virtually and the object bounds provide the viewport into that virtual position. To track and measure this virtual positioning, there are two internal Storyboard variables grd_xoffset and grd_yoffset that are used to determine the virtual object's position relative to its actual position. The content is aligned with the top of the control when the grd_yoffset value is 0 and the content appears to be moving down when the grd_yoffset value is negative.

When scrolling is enabled in the properties for an object, Storyboard Engine tracks any press, release, and motion events targeted at the object. While a press is active, the object tracks exactly to the user motion. Once the press turns to a release, the object scrolls based on the specified scrolling properties.


Vertical or horizontal scrolling


Number of pixels for the scrolling object to bounce when reaching the edge of the contents within the object

Left/Right Padding

Additional pixels at the left or right to allow scrolling past the edge of the contents within the object


If enabled, a scrolling table automatically has its cell boundaries snap to the specified pixel offset after a flick gesture is triggered. A scrolling layer has its offset snap to the nearest multiple of the specified offset

Enable Flick Gesture

If enabled, the object continues to scroll after a drag and release based on the momentum of the gesture

Max Duration

Maximum time in milliseconds that the object scrolls after a flick gesture


A number from 0 to 100 to determine the friction level of the scrolling object. With higher friction it becomes more resistant to moving when swiped and more inclined to slowing down when released

Wrap Content Horizontally/Vertically

If enabled, the content wraps back to the beginning or end if the object is scrolled outside the normal bounds. Although this can be used with the Enable Scrolling behavior, these two properties allow you to wrap content through Lua or a data change action.

Scroll Synchronization

When we have scrolling content, we frequently want some sort of visual indication of where we are within the context of that content, like a scrollbar. Storyboard doesn't dictate what type of visual presentation is used for this tracking, but we'll describe here how you might make a scrollbar using a simple fill render extension. This technique can be readily applied to any other visual representation and is demonstrated in the Scrollbar > Storyboard Sample as well as the Address Book Sample

The first thing that we want to consider is what information we want to convey to the user. For a simple scrollbar we will use a proportional measurement that represents the percentage that our y offset positionPercent = (-1 * objectYOffset) / (contentTotalHeight - objectHeight) Here, we'll assumed a vertically scrolling list, but the same principle applies for horizontally scrolling. With this positionPercent we have a representation of where our viewport is with respect to the total content available.

In order to apply this formula to synchronize a scrollbar representation with the content as it scrolls, we need to have a notification of the scroll change. This can be accomplished by making an event association with a variable as described in Triggering Events on Variable Changes. The variable that we want to bind an event to will be the internal variable grd_yoffset on the model object that we are scrolling.

With an event bound to an action, we might structure a synchronization function that might look something like the following:

-- Assume we are synchronizing a table named Layer.MyTable
function CBSyncScrollIndicator()
    -- These values could be cached, only yoffset would be changing normally
    local tableInfo = gre.get_table_attrs
    ("Layer.MyTable", "height", "yoffset", "rows")
    local cellInfo = gre.get_table_cell_attrs("Layer.MyTable", 1, 1, "height")
    local totalHeight = tableInfo.rows * cellInfo.height
    local positionPercent = (-1 * tablInfo.yoffset) / 
    (totalHeight - tableInfo.height)
    -- Now apply the position_percent to your scrollbar object
Was this article helpful?
0 out of 0 found this helpful