Skip to content

Overview

Usage

The TMSFMXNativeUICollectionView class manages an ordered collection of data items and presents them using customizable layouts. Collection views provide the same general function as table views except that a collection view is able to support more than just single-column layouts.

With this implementation, the visual representation is based on a template, which is available for the header, footer and the item. The TMSFMXNativeUICollectionView component comes with a designer that allows creating and modifying these templates. Each template allows adding various controls such as a label, image, button, stepper, etc... The template control is stored and accessible separately as a non-visual component.

Methods

Methods name Description
AddFooterTemplateButton A set of overloads that adds a button template control to the Footer template.
AddFooterTemplateCheckBox A set of overloads that adds a checkbox template control to the Footer template.
AddFooterTemplateControl A set of overloads that allows adding a template control the the footer template. Additional properties need to be set to the template control result or parameter depending on the type of overload that is chosen.
AddFooterTemplateImageView A set of overloads that adds an imageview template control to the Footer template.
AddFooterTemplateLabel A set of overloads that adds a label template control to the Footer template.
AddFooterTemplateProgressView A set of overloads that adds a progressview template control to the Footer template.
AddFooterTemplateStepper A set of overloads that adds a stepper template control to the Footer template.
AddFooterTemplateSwitch A set of overloads that adds a switch template control to the Footer template.
AddFooterTemplateTextField A set of overloads that adds a textfield template control to the Footer template.
AddFooterTemplateTextView A set of overloads that adds a textview template control to the Footer template.
AddHeaderTemplateButton A set of overloads that adds a button template control to the Header template.
AddHeaderTemplateCheckBox A set of overloads that adds a checkbox template control to the Header template.
AddHeaderTemplateControl A set of overloads that allows adding a template control to the header template. Additional properties need to be set to the template control result or parameter depending on the type of overload that is chosen.
AddHeaderTemplateImageView A set of overloads that adds an imageview template control to the Header template.
AddHeaderTemplateLabel A set of overloads that adds a label template control to the Header template.
AddHeaderTemplateStepper A set of overloads that adds a stepper template control to the Header template.
AddHeaderTemplateSwitch A set of overloads that adds a switch template control to the Header template.
AddHeaderTemplateTextField A set of overloads that adds a textfield template control to the Header template.
AddHeaderTemplateTextView A set of overloads that adds a textview template control to the Header template.
AddItemTemplateButton A set of overloads that adds a button template control to the item template.
AddItemTemplateCheckBox A set of overloads that adds a checkbox template control to the item template.
AddItemTemplateControl A set of overloads that allows adding a template control to the item template. Additional properties need to be set to the template control result or parameter depending on the type of overload that is chosen.
AddItemTemplateImageView A set of overloads that adds an imageview template control to the item template.
AddItemTemplateLabel A set of overloads that adds a label template control to the item template.
AddItemTemplateProgressView A set of overloads that adds a progressview template control to the item template.
AddItemTemplateStepper A set of overloads that adds a stepper template control to the item template.
AddItemTemplateSwitch A set of overloads that adds a switch template control to the item template.
AddItemTemplateTextField A set of overloads that adds a textfield template control to the item template.
AddItemTemplateTextView A set of overloads that adds a textview template control to the item template.
DeselectItem / DeselectItems / DeselectAllItems Deselects a specific or multiple item(s) identified with a section and row parameter.
GetFooterTemplateControl Returns a footer template control with a specific section, row and id parameter.
GetHeaderTemplateControl Returns a header template control with a specific section, row and id parameter.
GetItemTemplateControl Returns an item template control with a specific section, row and id parameter.
ReloadData Reloads the complete CollectionView, discarding and re-initializing items, headers and footers.
ReloadItem / ReloadItems Visually update a single or an array of TCollectionViewItem with a section and row parameter.
ReloadSection / ReloadSections Visually update a single or an array of Integer with a section parameter. Each reload of a section will also reload all items that the section holds.
ScrollToItem Scrolls to a specific item with a section and row parameter. Optionally allows passing the scrollposition and whether scrolling needs to be performed with or without animation.
SelectedItems Returns an array of selected items.
SelectItem / SelectItems / SelectAllItems Selects and scrolls to a specific or multiple item(s) identified with a section and row parameter. Optionally allows passing the scrollposition and whether scrolling needs to be performed with or without animation.
VisibleItems Returns an array of visible items.

Public Events

Important note

Events that might require additional iOSApi units and have native iOS parameters, use only when the published events do not suffice

Events name Description
OnAddItemBackground Event called when the default background view is added, allowing for more customization.
OnAddItemSelectedBackground Event called when the default selected background view is added, allow for more customization.
OnApplyFooterValues Event called to allow more customization on the footer view after the template controls values are applied.
OnApplyHeaderValues Event called to allow more customization on the Header view after the template controls values are applied.
OnApplyItemBackground Event called to allow more customization on the background view. This event differs with the OnAddItemBackground in a way that it is called when an item is being re-used instead of initialized. When the background remains static and does not change when scrolling, interacting with the items. The OnAddItemBackground event needs to be used, else the OnApplyItemBackground.
OnApplyItemSelectedBackground Event called to allow more customization on the selected background view. This event differs with the OnAddItemSelectedBackground in a way that it is called when an item is being re-used instead of initialized. When the selected background remains static and does not change when scrolling, interacting with the items. The OnAddItemSelectedBackground event needs to be used, else the OnApplyItemSelectedBackground.
OnApplyItemValues Event called to allow more customization on the item view after the template controls values are applied.
OnInitializeFooterTemplate Event called to allow more customization on the footer view after the template controls are created and added to the footer. This event is only called when the footer is created. Use this event if the changes you have made afterwards remain static else use the OnApplyFooterValues event.
OnInitializeHeaderTemplate Event called to allow more customization on the header view after the template controls are created and added to the header. This event is only called when the header is created. Use this event if the changes you have made afterwards remain static else use the OnApplyHeaderValues event.
OnInitializeItemBackground Event called with a native iOS UIView parameter that represents the item view and optionally allows creating an item background view that is used to apply the Options.ItemBackgroundColor property. Setting the ACreate parameter to false allows you to create your own native background view.
OnInitializeItemSelectedBackground Event called with a native iOS UIView parameter that represents the item view and optionally allows creating an item selected background view that is used to apply the Options.ItemSelectedBackgroundColor property. Setting the ACreate parameter to false allows you to create your own native selected background view.
OnInitializeItemTemplate Event called to allow more customization on the item view after the template controls are created and added to the item. This event is only called when the item is created. Use this event if the changes you have made afterwards remain static, else use the OnApplyItemValues event.

Published Events

The most important events are listed below, events such as an OnItemButtonClick, OnItemStepperValueChanged and equivalents for Header and Footer are not listed. These events depend on the kind of template that is constructed and used at runtime.The CollectionView is implemented with a virtual mode and requires some of the events that are listed below (marked in red).

Events name Description
OnGetItemBackgroundColor Event called to retrieve the background color of an item.
OnGetItemSelectedBackgroundColor Event called to retrieve the background color of an item used in selected state.
OnGetInsetForSectionAtIndex Event called to retrieve the inset for a section at a specific index.
OnGetMinimumInteritemSpacingForSectionAtIndex Event called to retrieve the minimum spacing between items on the same line in a section.
OnGetMinimumLineSpacingForSectionAtIndex Event called to retrieve the minimum spacing between lines in a section.
OnGetReferenceSizeForFooterInSection Event called to retrieve the reference size of the footer in a specific section.
OnGetReferenceSizeForHeaderInSection Event called to retrieve the reference size of the header in a specific section.
OnGetSizeForItemAtIndexPath Event called to retrieve the size for an item at a specific section and row.
OnDidSelectItem Event called when an item is selected.
OnDidDeselectItem Event called when an item is deselected.
OnShouldSelectItem Event called before an item will be selected. You can use this event to prevent selection of specific items.
OnShouldDeselectItem Event called before an item will be deselected. You can use this event to prevent deselection of specific items.
OnGetNumberOfSections Event called to retrieve the number of sections in the ColectionView. When this method is not implemented, the CollectionView returns 1 section by default.
OnGetNumberOfItemsInSection Event called to retrieve the number of items in the CollectionView. When this method is not implemented, the CollectionView returns 5 items per section by default.
OnAddHeaderControl Event called when a header template control is initialized. Implement this event to set properties on a specific template control that remains static during the usage of the CollectionView.
OnAddFooterControl Event called when a footer template control is initialized. Implement this event to set properties on a specific template control that remains static during the usage of the CollectionView.
OnAddItemControl Event called when an item template control is initialized. Implement this event to set properties on a specific template control that remains static during the usage of the CollectionView.
OnApplyHeaderValue Event called when a header template control will apply its values. Implement this event to set properties on a specific template control that is dynamic and changes it values depending on section parameter.
OnApplyFooterValue Event called when a footer template control will apply its values. Implement this event to set properties on a specific template control that is dynamic and changes it values depending on the section parameter.
OnApplyItemValue Event called when an item template control will apply its values. Implement this event to set properties on a specific template control that is dynamic and changes it values depending on the section and row parameter.

Templates

The CollectionView core is based on templates. Each section in the CollectionView consists of a header, footer and a number of items (elements). During creation, these elements are initialized and reused where possible, the CollectionView reads the controls inside the template, creates them and triggers a set of events (explained in the table of public and published events) that can be used to assign a value to a specific control inside an element based on the section and row parameter.

For header and footers, the row parameter will always be 0.

On CollectionView level, the template used to visualize an element is stored inside a generic list of TTMSFMXNativeUICollectionViewTemplateControl. This class has a number of descendants that define a native iOS control that can be used inside an element.

First Initialization

Before the CollectionView will start displaying sections, with optional header and footer, the CollectionView needs 2 events implemented. The first one is the OnGetNumberOfSections which returns 1 by default, if the event is not implemented. The second one is the OnGetNumberOfItemsInSection which returns 5 by default and needs to be mapped to the number of items / sections in your data structure. Afterwards, you can start adding template controls to visualize your data per item and / or section. In the code sample below, we add 2 sections, and respectively 5 and 3 items.

procedure TForm1.TMSFMXNativeUICollectionView1GetNumberOfItemsInSection(
  Sender: TObject; ASection: Integer; var ANumberOfItems: Integer);
Begin
  if ASection = 0 then
    ANumberOfItems := 5
  else
    ANumberOfItems := 3;
end;

procedure TForm1.TMSFMXNativeUICollectionView1GetNumberOfSections(
  Sender: TObject; var ANumberOfSections: Integer);
begin
  ANumberOfSections := 2;
end;

Adding template controls

Programmatically adding a control to the template of an element can be done with on of the various functions that are listed in the table above. Each element has its own template and thus its own set of functions. For an item the function starts with “AddItemTemplate”, for a header and footer respectively “AddHeaderTemplate” and “AddFooterTemplate”. The second part is based on the type of template control you wish to add to the element. Below is a sample of adding a label to the item template.

procedure TForm1.FormCreate(Sender: TObject);
var
  lbl: TTMSFMXNativeUICollectionViewTemplateLabel;
begin
  lbl := TMSFMXNativeUICollectionView1.AddItemTemplateLabel(10, 10, 100, 25, 'Hello World !');
end;
The code adds a label template control descendant to the item template collection that is located under the Template property on CollectionView level. As explained in the previous chapter, the CollectionView then loads and initializes the header, footer and item elements and loops through the template collection of each element. In this sample, a native iOS UILabel will be added to the item.

Initializing / modifying values

After defining the template for either the header, footer and / or the item, the CollectionView initializes the elements and creates a native iOS control for each template control. The CollectionView manages each element separately in memory and reuses its elements where possible.

The CollectionView does not manage a separate data structure, so the data that needs to be visualized will need to be passed by implementing some events. The “First Initialization” chapter already mentioned events to determine how many sections and items are going to be displayed. Next, after adding template controls to the header, footer and / or item with optionally default values, the data can be mapped on the control by implementing 2 events. These events are also called per element which means that we have an equivalent for the header, footer and item. In this sample code, we continue with our label template control that we have programmatically added.

The code shows how to define a default font, font size and text color that will be applied to all items.

procedure TForm1.FormCreate(Sender: TObject);
var
  lbl: TTMSFMXNativeUICollectionViewTemplateLabel;
begin
  lbl := TMSFMXNativeUICollectionView1.AddItemTemplateLabel(10, 10, 100, 25, 'Hello World !');
  lbl.Font.Name := 'Helvetica Bold';
  lbl.Font.Size := 18;
  lbl.TextColor := TAlphaColorRec.Red;
end;

Running the application will show a CollectionView with 5 items per section, with red bold text and the default value “Hello World” that is set in the FormCreate.

ttmsfmxnativeuicollectionview1

As explained, each label has the same color, font and text based on the template control of the item element. To modify these default values dynamically, we will need to implement an event that manages this. The OnApplyItemValue event is called with a section and row parameter and allows you to modify the value of the item. There are also equivalents for the header and footer that will be demonstrated after adding a template control to the header as well.

The code below shows how to access the label with a special helper function that is available in the FMX.TMSNativeUICollectionView unit to detect if the template control is a Label control. Each control inherits from the base control and is passed as a parameter of this event.

procedure TForm1.TMSFMXNativeUICollectionView1ApplyItemValue(Sender: TObject;
  AControl: TTMSFMXNativeUICollectionViewTemplateControl; ASection,
  ARow: Integer);
begin
  if IsLabel(AControl) then
    AsLabel(AControl).Text := 'Item ' + inttostr(ASection) + ':' + inttostr(ARow);
end;

ttmsfmxnativeuicollectionview2

Now, the header is visible as well, but does not show a template control, so we can use the same approach as like we did with the item, and add a control to the header template and modify its value afterwards through the appropriate event. The same could be done for the footer, but then you would need to set the FooterVisible property to true which is located under the Options property. The complete code for this sample can be found below:

procedure TForm1.FormCreate(Sender: TObject);
var
  lbl: TTMSFMXNativeUICollectionViewTemplateLabel;
begin
  lbl := TMSFMXNativeUICollectionView1.AddItemTemplateLabel(10, 10, 100, 25, 'Hello World !');
  lbl.Font.Name := 'Helvetica Bold';
  lbl.Font.Size := 18;
  lbl.TextColor := TAlphaColorRec.Red;

  lbl := TMSFMXNativeUICollectionView1.AddHeaderTemplateLabel(10, 10, 100, 25, '');
  lbl.Font.Name := 'Helvetica Bold';
  lbl.Font.Size := 22;
  lbl.TextColor := TAlphaColorRec.Blue;
end;

procedure TForm1.TMSFMXNativeUICollectionView1ApplyHeaderValue(
  Sender: TObject; AControl: TTMSFMXNativeUICollectionViewTemplateControl;
  ASection, ARow: Integer);
begin
  if IsLabel(AControl) then
    AsLabel(AControl).Text := 'Section ' + inttostr(ASection);
end;

procedure TForm1.TMSFMXNativeUICollectionView1ApplyItemValue(Sender: TObject;
  AControl: TTMSFMXNativeUICollectionViewTemplateControl; ASection,
  ARow: Integer);
begin
  if IsLabel(AControl) then
    AsLabel(AControl).Text := 'Item ' + inttostr(ASection) + ':' + inttostr(ARow);
end;

procedure TForm1.TMSFMXNativeUICollectionView1GetNumberOfItemsInSection(
  Sender: TObject; ASection: Integer; var ANumberOfItems: Integer);
begin
  if ASection = 0 then
    ANumberOfItems := 5
  else
    ANumberOfItems := 3;
end;

procedure TForm1.TMSFMXNativeUICollectionView1GetNumberOfSections(
  Sender: TObject; var ANumberOfSections: Integer);
begin
  ANumberOfSections := 2;
end;

ttmsfmxnativeuicollectionview3

Identifiers

In the sample above, we have added one label to the header and one to the item template. By default each template control is uniquely identified by its index. If you wish to add an additional template label to the item, the identifier is incremented and accessible in the order that they are added to the template. The identifier starts from 1 for the first item. The code of the OnApplyItemValue modified with a “description label” could then be implemented like the sample below:

procedure TForm1.TMSFMXNativeUICollectionView1ApplyItemValue(Sender: TObject;
  AControl: TTMSFMXNativeUICollectionViewTemplateControl; ASection,
  ARow: Integer);
begin
  if IsLabel(AControl) and (AControl.GetViewID = 1) then
    AsLabel(AControl).Text := 'Title ' + inttostr(ASection) + ':' + inttostr(ARow);

  if IsLabel(AControl) and (AControl.GetViewID = 2) then
    AsLabel(AControl).Text := 'Description ' + inttostr(ASection) + ':' + inttostr(ARow);
end;

If you have a special template control that needs to be accessible in an easy way, you can specify an ID to your template control. The ID property needs to be 1 or higher and is returned by the GetViewID function to identify the correct control. If you have multiple template controls of the same type and want to manage them with an easier accessibility, this is the way to identify them.

Interaction

The CollectionView supports a variety of template controls such as a label, imageview, progressview but also interactable controls such as a button. Adding a button is done in the same way as adding a label, can optionally and uniquely be identified and is also accessible to modify its values dynamically.

The CollectionView exposes events that are triggered when clicking a button, editing text in a textview or toggling the switch,with a section and row parameter.

Designtime editor

Programmatically adding, modifying and positioning controls can be useful to quickly have a rough idea on how your application would possibly look like. You can then concentrate on the data structure, implement interaction, selection, database handling, etc…. and handle the visualization afterwards. It might also be sufficient if you only have a label and an image and they are positioned without indenting, under eachother with the image taking up the remaining space after substracting the label height from the item height, but this will be easier said than done in some cases.

To cover the “easier said than done” part, we have created a designtime template editor that acts as a helper to create a template for the header, footer and / or item element. Under the Template property on CollectionView level you will notice three templates. Click on the three dots next to the template of choice to start the editor.

The editor will display a dotted rectangle that represents the boundaries of the element depending on the chosen template. On the left you can add template controls, position them relatively inside the element rectangle. A newly created template control is accessible as a non-visual component both at designtime and at runtime. It can also be removed as easily as it has been added. Below is the template of the item element shown inside the editor, and the result after the application is started and the data is loaded.

ttmsfmxnativeuicollectionview4 ttmsfmxnativeuicollectionview5

Performance

The CollectionView manages a state where it checks if a property is modified, sets a flag and updates the appropriate properties on the template control in one of the OnApply*Value events, but each control that is added to the template is passed as a parameter to this event so you can manipulate the data and visual aspects. When having multiple controls that remain identical for each element during the lifetime of the CollectionView, such as image shadows, text, buttons it is unnecessary to call the OnApply*Value event for these template controls. This will affect performance in a positive way and will allow you to manage the controls that really matter for your application.

When adding a new template control, you will notice a State property that is being set to csDynamic by default. In the demo you will notice by selecting the shadow item template control that the State property is being set to csStatic as the shadow is identical for each item.