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
and 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
> 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
and selecting > or by dragging a from the editor palette. The 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}) end
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(“layer.table.name.%d.1”, row)] = string.format(“%s %s”, contacts[row].first_name, contacts[row] .last_name) data[string.format(“layer.table.number.%d.1”, row)] = contacts[row].number end gre.set_data(data) end
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 | 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
or 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 section of the . 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.