List control
SCADE 2.0 - December 2021
Sourcecode
Please see the UgListControlDemo project for the source code created in this chapter. See Installing examples for information on how to download the examples from https://github.com/scadedoc/UgExamples/tree/master/UgListControlDemo2
Introduction
Our list control is very powerful because it's very versatile. You can configure it to do many things.
- Its can contain list elements of different types
- Each list element can be composed of many other elements
- You can hide and show certain elements programmatically
- You can change a lot of the characteristics by simply binding it to control variables
- The list control uses native graphics as well as platform specific behaviour, i.e
- Controls within the list control such as label or button are mapped to its respective native iOS and Android platform
- Drag and drop & slide or any touch movement use the algorithms of the respective native iOS and Android platform and are native
Displaying an array in a list control
In this example, we want to display the first 100 most popular dog names (from 2020) together with a breed and id.
Add list control to page
- We use the contraints box to make sure it uses all the space available

Add controls to list template
We add the controls we want to see in each list element
- Each list control contains a list of list elements
- Each list element contains the same visual controls to display the data
- The list element is designed using the the list controls's list element template
- In this example, we added 3 text labels into a gridView

Define Data Model
- We use the Dog class to display a list of dog names and breeds
- We inherit from EObject
import ScadeKit
class Dog : EObject {
// please make sure you annotate each variable with the type
// for SCADE to more identify and leverage the type information
// currently, you must inherit from EObject
var id: String
var name: String
var ageInYears: Int
var breed: String
init(id: String, name: String, breed: String, ageInYears: Int) {
self.id = id
self.name = name
self.breed = breed
self.ageInYears = ageInYears
}
}
Bind data to controls
Bind the list elements visual control to the data
- In order to bind the view to the model, we use the SCDWidgetsElementProvider class
- Its set using .elementProvider
- You set an instance of SCDWidgetsElementProvider and add the logic that binds the data to the list element's visual controls
- The template parameter is of type SCDWidgetsGridView. Use the getWidgetByName method to retrieve a reference to the visual control and set the data from the Dog class instance:
class MainPageAdapter: SCDLatticePageAdapter {
var dogs: [Dog] = []
// page adapter initialization
override func load(_ path: String) {
super.load(path)
self.list1.elementProvider = SCDWidgetsElementProvider { (dog: Dog, template) in
(template.getWidgetByName("dogName") as? SCDWidgetsLabel)?.text = dog.name
(template.getWidgetByName("dogBreed") as? SCDWidgetsLabel)?.text = dog.breed
(template.getWidgetByName("dogId") as? SCDWidgetsLabel)?.text = dog.id
}
}
}
Set the data source of the control
- Define the source of data by setting the items property
- Its a collection of data objects
list1.items = Dogs().dogs
List Control lists data successfully

Add handler to process row click / item selected event
To add logic whenever a row is clicked,
- Add the event handler to the .onItemSelected
- The event handler is called SCDWidgetsItemSelectedEventHandler
// the onItemSelected handler is fired when we click a list's row
list1.onItemSelected.append(
SCDWidgetsItemSelectedEventHandler { event in
if let dog = event?.item as? Dog {
print("Hello \(dog.name)")
}
}
)
Create clicked animation effect on list element
This chapter explains on how to change the background when a row has been clicked.
We add another handler to the onItemSelected handler array. This time, we use the event's element property to access the list's list element SCDWidgetsListElement and set the animation effect
- We use gold as a start color
- We use the original color as the end color
- We create an animation effect. We animate the fill property (to fill the background)
- We apply the animation effect to the background of the list element
- Accessing the SVG component of the SCDWidgetsListElement requires understanding of the underlying API. The code to do this is encapsulated in a helper class and the component exposed as backgroundSvgRect
// add animation when list row is clicked
list1.onItemSelected.append(
SCDWidgetsItemSelectedEventHandler { [weak self] event in
if let listElement = event?.element as? SCDWidgetsListElement,
let backgroundColor = listElement.backgroundColor,
let self = self {
// We want to animate bacground color from gold to the original color
let fromColor = SCDSvgRGBColor.gold
let toColor = self.colorConvert(backgroundColor)
// Lets animate fill property
let anim = SCDSvgPropertyAnimation("fill", from: fromColor, to: toColor)
anim.duration = 0.4
anim.repeatCount = 1
anim.delay = 0.2
anim.deleteOnComplete = true
listElement.backgroundSvgRect?.animations.append(anim)
}
})
func colorConvert(_ color: SCDGraphicsRGB) -> SCDSvgRGBColor {
return SCDSvgRGBColor(red: color.red, green: color.green, blue: color.blue, alpha: color.alpha)
}
Ensure background is set with fill color
The list element's background can be set to a. Nothing b. Image c. FIll Color
If the background is set to Nothing, no visual component exists and the background cannot be set. Therefore, its mandatory that you set the background to a background color:

Access list element's graphic representation
The list element has a background represented by an SVGRect element. To access this element we use the following extension
extension SCDWidgetsWidget {
var backgroundSvgImage: SCDSvgImage? {
return self.backgroundSvgElement as? SCDSvgImage
}
var backgroundSvgRect: SCDSvgRect? {
return self.backgroundSvgElement as? SCDSvgRect
}
private var backgroundSvgElement: SCDSvgElement? {
let background = (self.drawing as? SCDSvgContainerElement)?.children[0]
if let container = (background as? SCDSvgContainerElement), !container.children.isEmpty {
return container.children[0]
} else {
return nil
}
}
}
Row selected visual effect video
Updated over 1 year ago