Creating Lists and Tables

When you have a list of repetitive visual information to display then Storyboard's table's are a convenient tool to use. A table is equivalent to a control repeatedly applied, almost as a stamp or a template, to a grid of row and columns. A table with a single column or row can very effectively be used to represent list items. The controls that are created based on the number of rows and columns are referred to collectively as table cells. A table cell is a control at a particular one (1) based row and column offset. Tables offer automatic scrolling_layers capabilities, both interactively through touch events or programmatically using the Table Navigate and Table Scroll actions.

To create a scrolling table that is dynamically populated with data, you will generally follow these steps:

  • Create a table

  • Bind variables for dynamic table cell content

  • Define the list data

  • Resize the table to accommodate the list data

  • Assign cell variables with the list data

The data that is being used for the table can come from a variety of sources, but is generally processed into the table cell variables using Lua. For example, your data from a database, a file on the filesystem or dynamically injected into the application as an event via Storyboard IO. Once you have your data you will be able to process it and assign the appropriate fields into cell variables that the control templates reference. The following is an example of Lua data to be used in a table that was taken from the AddressBook > Sample application shipped with Storyboard:

local contacts = {
       {image=”images/john_smith.jpg”, first_name=”John”, 
       last_name=”Smith”, number=”453-555-1685”},
       {image=”images/jane_smith.jpg”, first_name=”Jane”,
       last_name=”Smith”, number=”466-555-1686”}

With an idea of what the table data looks like, you can build a control template to be used in the table that will display this content. Tables are created the same way as standard controls, by right clicking in the editor or Application View and selecting Add > Table or by dragging a Table Control from the editor palette. The New Table dialog offers a few additional configuration options to allow you to specify an initial number of rows, columns as well as defining the render extensions for the table and the first table cell control template.

In the case of the data we have above, we might consider creating a table with a single column and a table cell control template that contains an image render extension (for the image) and a two text render extensions (for the name and number. The image name, and text content properties would each be bound to a table cell variable to allow each table cell to contain a unique value.

In general the number of rows and columns that you create on a table that will contain dynamic content is only going to be as large as you need it to be to show the design intent. With external data populating the table, you will size the table appropriately using the Lua API gre.set_table_attrs(). In our sample we have our data in a Lua table so we can easily extract determine the number or rows for the table to be, your application data may use a different protocol.

function CBInitTable()
    -- Assume that tableLayer.table refers to our table
    gre.set_table_attrs(“tableLayer.table”, {rows = #contacts})

This will configure the internal size of the table to the size of our contacts list. Once the table is dynamically sized, we can start filling content by assigning values to our table cell variables. This represents the transfer of model data to visual domain data as the Storyboard variables represent content that will be directly reflected in the UI. Table cell variables are accessed using their basename and a .row.col index:

function CBInitTable()
    -- Assume that tableLayer.table refers to our table
    gre.set_table_attrs(“tableLayer.table”, {rows = #contacts})

    -- Assume we've created cell variables named image, name and number
    local data = {}
    for (row=1,#contacts) do
        data[string.format(“tableLayer.table.image.%d.1”, row)]
        = contacts[row].image
        data[string.format(“”, row)]
        = string.format(“%s %s”, contacts[row].first_name, contacts[row]
        data[string.format(“layer.table.number.%d.1”, row)]
        = contacts[row].number 

With this functionality in place the table is now being sized appropriately and it's display content is being set.

If the content is too large to fit within the bounds of the table, then we will want to consider some sort of scrolling strategy. Storyboard offers two different scrolling strategies:

Cell based scrolling using Actions and cell re-positioning
Pixel based scrolling using table xoffset and yoffset

Both internally modify the x and y offsets, so it is safe to mix and match between the two techniques.

The cell based scrolling is performed by changing the cell that is located at the top left most corner of the visual table. This is performed using the Table Navigate or Table Scroll actions. These actions provide flexibility with regards to the roll-over of content as well since they are simply manipulating which cells are being displayed.

The pixel based scrolling is generally what users are expecting within a modern interactive UI. This scrolling is enabled by selecting the Enable Scrolling property in the table's Table section of the Properties View. Enabling this option will unlock various properties that regulate the rate at which the table scrolls through its decay and virtual friction. These properties, and the ability to synchronize scrolling content with other controls is discussed in Working with Scrolling Content.

Most list based tables will only have a single column or single row and each cell will be rendered the same way but with different content (mapped via table cell variables). From time to time it is desirable to have different rendering capabilities for different cells and this can be done using different table cell templates. Storyboard tables only support different customized cell templates on a per column basis. To use a different table cell template, select the Cell Templates tab in the table properties section. Here you can add new table cell templates and assign those new templates to one or more table columns. It is recommended to name the table templates so that they can be more easily distinguised from one another. Once a table template is created, then selecting the table cell in the corresponding table column will edit and configure that particular template rather than the default one.

For a more flexible and custom approach developers looking for per cell customization may want to explore using cloned controls and a custom layout on a scrolling layer rather than using tables.

Was this article helpful?
0 out of 0 found this helpful