Collection views
UICollectionView controls
The UICollectionView is a key view type in UIKit and Apple’s Human Interface Guidelines. The Fiori Design Language utilizes collection views in a number of floorplans, especially Object Details, Overview, as well as in the Gallery View, Object CollectionView and Attachments section of the Create View.
The SAPFiori utilizes UICollectionView instances in a number of controls. When the content for those controls should be managed by the developer, it typically exposes the collection view as a public property in the API. A developer should use the regular UIKit API’s to configure and populate the item views of the collection, and handle things like taps and transitions.
The SAPFiori controls exposing a collection view property include:
FUITableViewCollectionSectionwith embeddedFUICollectionViewTableViewCellFUIAttachmentsController
These controls implement some context-specific behavior for the collection view–usually around layout and sizing–but when starting to implement a custom collection case, the starting point for a developer should be to work directly with *UICollectionView***.
Then, the developer can use one or more of the UICollectionViewLayout types from the SAPFiori framework to govern the item layout, and/or choose from the available UICollectionViewCell subclasses in the framework to match the design specification.
UICollectionViewLayout Subclasses
FUICollectionViewLayout.horizontalScroll
The .horizontalScroll layout extends UICollectionViewFlowLayout. This layout should be used when the user should pan horizontally in the collection view, to view items off-screen to the left or right. Items in a section extend in a single row to infinity, so items will not wrap to new lines.
A developer should set the itemSize property of the layout to specify the standard dimensions of the cell items. Alternatively, the developer can implement the UICollectionViewDelegateFlowLayout to specify unique sizes for each cell item.
A developer may optionally return views to the UICollectionViewDataSource collectionView(_:viewForSupplementaryElementOfKind:at:) method, to set ‘supplementary’ views to the collection view’s section header or footer. Multiple sections are supported, though cells in all sections will scroll simultaneously, so single section collections are most common.
Important
this layout ignores the estimatedItemSize property, even if it is assigned.

FUICollectionViewLayout.horizontalFlow
The .horizontalFlow layout extends UICollectionViewFlowLayout by adding a new optional property: minimumScaledItemSize. minimumScaledItemSize enables the dimensions of the collection view cell items to be scaled upwards, to fill the width of the collection view’s contentSize.
The developer can allow the layout to scale any number of cell items to fit the contentSize width, or can set a predetermined number of items that should fit the contentSize width by setting the numberOfColumns property. This is useful when the number of items rendered in the collection view varies on different screens, but a common size is desired.
The .horizontalFlow layout also controls the inter-item spacing and line spacing, so that the minimumInteritemSpacing and minimumLineSpacing values provided by the developer are used precisely, rather than being adjusted by the AutoLayout engine.
With the introduction of this new size property, the UICollectionViewFlowLayout item size is managed by the following priority:
- Autolayout system, if
estimatedItemSizeis set not equal toCGSize.zero FUICollectionViewHorizontalFlowLayout, withnumberOfColumnsproperty, ifminimumScaledItemSizeis set not equal toCGSize.zeroFUICollectionViewHorizontalFlowLayout, ifminimumScaledItemSizeis set not equal toCGSize.zeroitemSizeproperty (Note:collectionView(_:layout:sizeForItemAt:)value is ignored)
Default Flow Layout Behavior

Flow Layout Behavior, Using minimumScaledItemSize

FUICollectionViewLayout.autosizingColumnFlow
The autosizingColumnFlow resizes collection view cell items to lay them out according to a specified number of columns. All items per row are top-aligned, though the cell item height may vary, based upon the AutoLayout system’s height calculation for the cell. The leading/trailing edges of the first and last columns abut the respective margins of the content view.
The developer may specify the number of columns by setting the numberOfColumns property.
Collection view cell items supplied to the UICollectionViewDataSource.collectionView(_:cellForItemAt:) method for collection views utilizing this flow layout should be well-prepared for the AutoLayout engine to calculate content sizes, especially heights.

FUICollectionViewLayout.keyValueColumnFlow
The keyValueColumnFlow is a variant of the autosizingColumnFlow, with preconfigured layout characteristics for rendering collections of FUIKeyValueCollectionViewCell items.
minimumInteritemSpacingis set to 80.minimumLineSpacingis set to 24.sectionInsetis set toUIEdgeInsetsMake(0, 8, 0, 8).
-
UICollectionViewCellsubclass used for displaying business objects in acollectionView.Developer should use the
FUICollectionItemViewandFUIBaseItemCollectionViewCellAPI set to build the view.Usage
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUICollectionItemCell.reuseIdentifier, for: indexPath) as! FUICollectionItemCell cell.itemSize = .small cell.detailImageView.image = UIImage(named: "profile") cell.detailImageView.isCircular = true cell.title.text = "Franck Syren" cell.subtitle.text = "Java Developer" cell.status.text = "Available" cell.actionLayout = .pair cell.primaryButton.setImage(img, for: .normal) cell.secondaryButton.setImage(img, for: .normal) return cellTheming
nuiClass:fdlFUIItemCollectionViewCell {}Supported
TEXTclass paths:fdlFUIItemCollectionViewCell_title {} fdlFUIItemCollectionViewCell_subtitle {} fdlFUIItemCollectionViewCell_status {} fdlFUIItemCollectionViewCell_placeholder {}Supported
TEXTproperties:font-color: Color; font-style: UIFontTextStyle; text-line-clamp: Integer; text-align: NSTextAlignment;Supported
IMAGEclass paths:fdlFUIItemCollectionViewCell_detailImageView {}Supported
IMAGEproperties:
See moretint-color: Color;Declaration
Swift
@IBDesignable @MainActor open class FUIItemCollectionViewCell : FUIBaseItemCollectionViewCell<FUICollectionItemView>, FUIContentCopyable -
View component of
FUIItemCollectionViewCell. Typically not used directly by developer.Usage
let itemView = FUICollectionItemView() itemView.detailImageView.image = UIImage(named: "profile") itemView.detailImageViewSize = CGSize(width: 90, height: 90) itemView.title.text = "Franck Syren" itemView.subtitle.text = "Java Developer" itemView.status.text = "Available"Theming
nuiClass:fdlFUICollectionItemView {}Supported
TEXTclass paths:fdlFUICollectionItemView_title {} fdlFUICollectionItemView_subtitle {} fdlFUICollectionItemView_status {} fdlFUICollectionItemView_placeholder {}Supported
TEXTproperties:font-color: Color; font-style: UIFontTextStyle; text-line-clamp: Integer; text-align: NSTextAlignment;Supported
IMAGEclass paths:fdlFUICollectionItemView_detailImageView {}Supported
IMAGEproperties:
See moretint-color: Color;Declaration
Swift
@MainActor open class FUICollectionItemView : FUIImageCollectionItemView, FUITitleComponent, FUISubtitleComponent, FUIStatusComponent, FUISecondaryButtonControlComponent, FUIContentCopyable -
View component of
FUIImageCollectionViewCell. Typically not used directly by developer.Usage
let itemView = FUIImageCollectionItemView() itemView.detailImageView.image = UIImage(named: "profile") // To enable a default gradient layer behind the placeholder text. itemView.detailImageView.isGradientLayerEnabled = true // Set placeholder text. itemView.detailImageView.placeholder.text = "This is a placeholder" itemView.detailImageViewSize = CGSize(width: 90, height: 90)Theming
nuiClass:fdlFUIImageCollectionItemView {}Supported
IMAGEclass paths:fdlFUIImageCollectionItemView_detailImageView {}Supported
IMAGEproperties:
See moretint-color: Color;Declaration
Swift
@MainActor open class FUIImageCollectionItemView : FUIDrawingView, FUIDetailImageViewComponent -
UICollectionViewCellsubclass used for displaying business object’s image in acollectionView.Developer should use the
FUIImageCollectionItemViewAPI set to build the view.Usage
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIImageCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIImageCollectionViewCell cell.itemSize = .small cell.detailImageView.image = UIImage(named: "profile") cell.detailImageView.isCircular = trueTheming
nuiClass:fdlFUIImageCollectionViewCell {}Supported
IMAGEclass paths:fdlFUIImageCollectionViewCell_detailImageView {}Supported
IMAGEproperties:tint-color: Color;Declaration
Swift
@MainActor open class FUIImageCollectionViewCell : FUIBaseItemCollectionViewCell<FUIImageCollectionItemView> -
UITableViewCellcontaining aUICollectionView.Takes responsibility for correct layout and sizing for the items, for different screen dimensions.
See moreDeclaration
Swift
@MainActor open class FUIItemCollectionViewTableViewCell : FUIBaseCollectionViewTableViewCell -
A variant of
UICollectionViewCellwhich is very similar toSimplePropertyFormCellexcept that it’s not editable.keyName: The key of the cell.value: The value of the cell.
Code usage:
Register
FUISimplePropertyCollectionViewCellfor a collection view object.self.collectionView.register(FUISimplePropertyCollectionViewCell.self, forCellWithReuseIdentifier: FUISimplePropertyCollectionViewCell.reuseIdentifier)Dequeue a
FUISimplePropertyCollectionViewCellobject from a collection view’sdataSourcemethodcollectionView(_:cellForItemAt:)public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: FUISimplePropertyCollectionViewCell.reuseIdentifier, for: indexPath) as! FUISimplePropertyCollectionViewCell switch indexPath.item { case 0: cell.keyName = "Name" cell.value = "Broken Plates on Pole" case 1: cell.keyName = "Sort No." cell.value = "0001" default: break } return cell }Theming
Supported style classes
See morefdlFUISimplePropertyCollectionViewCell fdlFUISimplePropertyCollectionViewCell_keyLabel fdlFUISimplePropertyCollectionViewCell_valueTextFieldDeclaration
Swift
@MainActor open class FUISimplePropertyCollectionViewCell : NibDesignableFUIBaseCollectionViewCell -
FUIKeyValueCollectionViewCell is a variant of
UICollectionViewCelldefined inSAPFiori. It contains aUILabeland aUITextField.Code usage:
Register
FUIKeyValueCollectionViewCellfor a collection view object.self.collectionView.register(FUIKeyValueCollectionViewCell.self, forCellWithReuseIdentifier: FUIKeyValueCollectionViewCell.reuseIdentifier)Implement collection view’s dataSource method
collectionView(_:cellForItemAt:)
See morepublic func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: FUIKeyValueCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIKeyValueCollectionViewCell switch indexPath.item { case 0: cell.keyName = "Name" cell.value = "Broken Plates on Pole" case 1: cell.keyName = "Sort No." cell.value = "0001" default: break } return cell }Declaration
Swift
@MainActor open class FUIKeyValueCollectionViewCell : NibDesignableFUIBaseCollectionViewCell -
Set of
See moreUICollectionViewFlowLayouts occurring in Fiori Design Language.Declaration
Swift
public enum FUICollectionViewLayout -
This layout extends
UICollectionViewFlowLayout, by adding a new optional property:minimumScaledItemSize, which enables the collection view cell items’ dimensions to be scaled upwards, to fill the width of the collection view’scontentSize.The developer may allow the layout to scale any number of cell items to fit the
contentSizewidth, or, may set a pre-determined number of items which ought to fit thecontentSizewidth, by setting thenumberOfColumnsproperty. This is useful, when the number of items rendered in the collection view vary on different screens, but a common size is desired.This layout also controls the inter-item spacing, and line spacing, so that the
minimumInteritemSpacingandminimumLineSpacingvalues provided by the developer are used precisely, rather than being adjusted by the AutoLayout engine.Item will be scaled if you set following three properties(Set a number greater than zero to enable corresponding feature):
- estimatedItemSize: Scale item to the size provided by systemLayoutSizeFitting(_:).
- numberOfColumns: Scale item based on the aspect ratio of
itemSize. - minimumScaledItemSize: Scale item upwards to fill the row based on the aspect ratio of
minimumScaledItemSize.
Other configurations:
- isLayoutJustified: A boolean value indicating if adjusting inter-item spacing to make cells fit the full width.
- numberOfRows: Max number of rows allowed. Default value is 0, which means there is no limit on number of rows.
- isTopAligned: A boolean value indicating if items on the same row are top aligned.
Code usage
Assign an instance of FUIHorizontalScrollCollectionViewLayout to your collection view.
self.collectionView.collectionViewLayout = FUICollectionViewLayout.horizontalScrollImplement collectionView(_:cellForItemAt:) dataSource.
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIObjectCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIObjectCollectionViewCell //You may use any type of collection view cell here. //configue cell here //... return cell }Implement following methods if you need section header/footer. You can also set headerReferenceHeight/footerReferenceHeight to apply same height for all headers/footers.
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { let view = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "Header", for: indexPath) as! FUICollectionSectionHeaderFooterView //configue header/footer view here //... return view }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { switch section { case 0: return CGSize(width: 40, height: 40) default: return CGSize(width: 60, height: 60) }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { switch section { case 0: return CGSize(width: 40, height: 40) default: return CGSize(width: 60, height: 60) }
See moreDeclaration
Swift
@MainActor open class FUIHorizontalFlowCollectionViewLayout : UICollectionViewFlowLayout -
This layout should be used when the user should pan horizontally in the collection view, to view items off-screen to the left or right. Items in a section extend in a single row to infinity, so items will not wrap to new lines.
A developer should set the
itemSizeproperty of the layout, to specify the standard dimensions of the cell items.Code usage
Assign an instance of FUIHorizontalScrollCollectionViewLayout to your collection view.
self.collectionView.collectionViewLayout = FUICollectionViewLayout.horizontalScrollImplement collectionView(_:cellForItemAt:) dataSource.
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIObjectCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIObjectCollectionViewCell //You may use any type of collection view cell here. //configue cell here //... return cell }Implement following methods if you need section header/footer. You can also set headerReferenceHeight/footerReferenceHeight to apply same height for all headers/footers.
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { let view = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "Header", for: indexPath) as! FUICollectionSectionHeaderFooterView //configue header/footer view here //... return view }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { switch section { case 0: return CGSize(width: 40, height: 40) default: return CGSize(width: 60, height: 60) }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { switch section { case 0: return CGSize(width: 40, height: 40) default: return CGSize(width: 60, height: 60) }
See moreDeclaration
Swift
@MainActor open class FUIHorizontalScrollCollectionViewLayout : UICollectionViewLayout -
The
FUIStandardAutoSizingColumnFlowLayoutresizes collection view cell items, to lay them out according to a specified number of columns. All items per row are top-aligned, though the cell item height may vary, based upon the AutoLayout system’s height calculation for the cell.Code usage
Assign an instance of FUIStandardAutoSizingColumnFlowLayout to your collection view.
self.collectionView.collectionViewLayout = FUICollectionViewLayout.autosizingColumnFlowImplement collectionView(_:cellForItemAt:) dataSource.
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIObjectCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIObjectCollectionViewCell //configue cell here //... return cell }Implement following methods if you need section header/footer. You can also set headerReferenceHeight/footerReferenceHeight to apply same height for all headers/footers.
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { let view = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "Header", for: indexPath) as! FUICollectionSectionHeaderFooterView //configue header/footer view here //... return view } }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { switch section { case 0: return CGSize(width: 40, height: 40) default: return CGSize(width: 60, height: 60) }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { switch section { case 0: return CGSize(width: 40, height: 40) default: return CGSize(width: 60, height: 60) }
See moreDeclaration
Swift
@MainActor open class FUIStandardAutoSizingColumnFlowLayout : FUIBaseCollectionViewLayout<FUIStandardAutoSizingColumnSectionLayoutManager> -
A subclass of
FUIStandardAutoSizingColumnFlowLayoutwhich resizes collection view cell items, to lay them out according to a specified number of columns. All items per row are top-aligned, though the cell item height may vary, based upon the AutoLayout system’s height calculation for the cell.minimumInteritemSpacingis set to 80 andminimumLineSpacingis set to 24 by default.sectionInsetis set to ‘top: 0, left: 8, bottom: 0, right: 8’.Declaration
Swift
@MainActor public class FUIKeyValueFlowLayout : FUIStandardAutoSizingColumnFlowLayout -
UITableViewCellsubclass, containing a full-frame collectionView. TheFUICollectionViewTableViewCellwill resize its height to accomodate all the items in collection view.## Usage
See morelet workOrders: [WorkOrder] = [] let businessObjects: [BusinessObject] = [] override public func viewDidLoad() { self.tableView.rowHeight = UITableView.automaticDimension self.tableView.register(FUICollectionViewTableViewCell.self, forCellReuseIdentifier: FUICollectionViewTableViewCell.reuseIdentifier) } // MARK: UITableViewDataSource override public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 2 } public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: FUICollectionViewTableViewCell.reuseIdentifier, for: indexPath) as! FUICollectionViewTableViewCell cell.collectionView.setCollectionViewLayout(FUICollectionViewLayout.autosizingColumnFlow, animated: false) cell.collectionView.dataSource = self cell.collectionView.delegate = self cell.collectionView.tag = indexPath.section switch indexPath.section { case 0: cell.collectionView.register(FUIObjectCollectionViewCell.self, forCellWithReuseIdentifier: FUIObjectCollectionViewCell.reuseIdentifier) case 1: cell.collectionView.register(FUIItemCollectionViewCell.self, forCellWithReuseIdentifier: FUIItemCollectionViewCell.reuseIdentifier) default: break } return cell } // MARK: UICollectionViewDataSource public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { switch collectionView.tag { case 0: let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIObjectCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIObjectCollectionViewCell let workOrder = workOrders[indexPath.item] cell.detailImage = workOrder.image cell.headlineText = workOrder.title return cell default: let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIItemCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIItemCollectionViewCell let businessObject = businessObjects[indexPath.item] cell.contentImage = businessObject.image cell.titleText = businessObject.title return cell } }Declaration
Swift
@MainActor open class FUICollectionViewTableViewCell : NibDesignableFUIBaseTableViewCell -
The reusable UI component implemented as a
UICollectionViewCell, allowing the developer to choose a Boolean value using a switch for a property.
The developer should set the following properties on the cell in their implementation of the
UITableViewDataSourcecellForRow(at:)function:keyName: The key name of the propertyvalue: The value of the property (Bool).isEditable: Indicates whether the cell’s value may be modified. The default istrue.
And, an
onChangeHandler:onChangeHandler: a handler closure that is invoked on changes to the value
The following is an example of usage in an application using
UIViewControllerandUICollectionViewDataSource:override func viewDidLoad() { super.viewDidLoad() self.collectionView.register(FUISwitchCollectionViewCell.self, forCellReuseIdentifier: FUISwitchCollectionViewCell.reuseIdentifier) } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UITableViewCell { let cell = collectionView.dequeueReusableCell(withIdentifier: FUISwitchCollectionViewCell.reuseIdentifier, for: indexPath) as! FUISwitchCollectionViewCell cell.keyName = "Confirmed" cell.value = myObject.isConfirmed cell.onChangeHandler = { newValue in myObject.isConfirmed = newValue } return cell }Theming
Supported style classes and attributes.
fdlFUISwitchFormCell { // Table view cell related attributes. // ... } fdlFUISwitchFormCell_title { // Font attributes font { -style | -name | -size } font-color // Number of lines text-line-clamp // Text alignment text-align } fdlFUISwitchFormCell_switch { tint-color // Knob color thumb-color { -enabled-selected | -enabled-unselected | -disabled-selected | -disabled-unselected } // Track color track-color { -enabled-selected | -enabled-unselected | -disabled-selected | -disabled-unselected } // Border color border-color { -enabled-selected | -enabled-unselected | -disabled-selected | -disabled-unselected } // View opacity view-alpha { -enabled-selected | -enabled-unselected | -disabled-selected | -disabled-unselected } }Note: As of iOS SDK 9.0, the version of
fdlFUISwitchFormCell_switchdescribed above is preferable to the version offdlFUISwitchFormCell_switchdescribed below (to achieve maximum UX design compliance).
See morefdlFUISwitchFormCell_switch { tint-color on-tint-color }Declaration
Swift
@MainActor open class FUISwitchCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUISwitchFormView> -
FUIInlineSignatureCollectionViewCellis aUICollectionViewCellsubclass that enables the drawing and capturing of a user’s signature.Usage Example:
let cell = collectionView.dequeueReusableCell(withIdentifier: FUIInlineSignatureCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIInlineSignatureCollectionViewCell cell.value = self.signatureImage cell.onChangeHandler = { [unowned self] newValue in self.signatureImage = newValue if let image = newValue { // save the signature image saveSignatureImage(image: image) } } return cellTheming
See Theming support in
See moreFUIInlineSignatureFormView.Declaration
Swift
@MainActor public class FUIInlineSignatureCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIInlineSignatureFormView>, FUITableAndCollectionCellUpdate -
The reusable UI component implemented as a
UICollectionViewCellto display or be edited as a stepper.A stepper is a visual representation of a user’s progress through a series of steps in a task, indicating how much the user has completed or how far they are from completing the task.
And an
onChangeHandler:onChangeHandler: a handler closure, which is invoked on changes to the value
Optionally, the developer may provide
hintText: hint text.isEditable: Indicates whether the cell’s value can be modified. The default istrue.maximumValue: The highest possible numeric value for the stepper. The default is 100.minimumValue: The lowest possible numeric value for the stepper. The default is 0.
The following is an example of usage in an application
UICollectionViewController:override func viewDidLoad() { super.viewDidLoad() self.collectionView.register(FUIStepperCollectionViewCell.self, forCellWithReuseIdentifier: FUIStepperCollectionViewCell.reuseIdentifier) } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIStepperCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIStepperCollectionViewCell cell.title = "Normal Stepper" cell.value = "5" cell.hintText = "hint text" // MARK: implement onChangeHandler cell.onChangeHandler = { newValue in // ... } cell.maximumValue = 10 cell.minimumValue = 0 // custom colors and fonts cell.setAttributes([.fuiBorderColor: UIColor.systemPurple], for: .title, state: .highlighted) cell.setAttributes([.fuiBorderColor: UIColor.systemYellow], for: .title, state: .normal) return cell }## Customize Style Using
tintAttributesSupported
keyView:setAttributes([.foregroundColor:, .font], for: .title, state: { .normal | .highlighted | .disabled })or directly set
textColorandfontfor the title.Supported
valueText:setAttributes([.foregroundColor:, .font], for: .valueText, state: { .normal | .disabled }) addAttributes([.fuiBorderColor:], for: .valueText, state: { .normal | .highlighted | .disabled })or directly set
textColorandfontfor the valueTextField.Supported
increaseButtonanddecreaseButton:setAttributes([.foregroundColor:], for: .icons, state: { .normal | .disabled })Supported
hintView:setAttributes([.foregroundColor:, .font:], for: .subtitle, state: { .normal | .disabled })###
.nssThemeSupported
keyView:fdlFUIStepperFormCell_keyText { font-color { -highlighted | -disabled } (Color) font-style { -highlighted | -disabled } (UIFont.TextStyle) }Supported
valueText:fdlFUIStepperFormCell_valueText { font-color { -disabled } (Color) font-style { -disabled } (UIFont.TextStyle) border-color { -highlighted | -disabled } (Color) }Supported
BUTTONclass paths:fdlFUIStepperFormCell_increaseButton { font-color { -disabled } (Color) } fdlFUIStepperFormCell_decreaseButton { font-color { -disabled } (Color) }Supported
hintView:
See morefdlFUIStepperFormCell_hintText { font-color { -disabled } (Color) font-style { -disabled } (UIFont.TextStyle) }Declaration
Swift
@MainActor open class FUIStepperCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIStepperView>, FUIFormCellextension FUIStepperCollectionViewCell: FUITintAttributesProvider -
The reusable UI component implemented as a
UICollectionViewCellto display a key-value pair property, which is integrated with aFUIListPickercontroller for displaying a list of values.title: The title of the property.valueText: The title of the property.value: The default selections.valueOptions: The list of optional values the user may choose from.allowsMultipleSelection: Indicates whether the user can select multiple values. The default istrue, meaning that, by default, the user may select multiple values.isEnabled: Determines whether the selection(s) can be modified or not. The default istrue.listPicker: TheFUIListPickerfor thisFUIListPickerCollectionViewCell.
Note that the display of the selections in the
valueLabelis the responsibility of the developer if thedataSourceproperty of thelistPickeris set. The developer needs to set the text of thevalueLabelto reflect the selections. Otherwise, if the developer setsvalueOptionsand leavesdataSourceoflistPickerasnil, then the text invalueLabelwill be set internally.Here are the code snippets in the app’s
UICollectionViewControllerimplementation: (The app’sUICollectionViewControllerneeds to be a subclass ofFUIFormCollectionViewController.)var propValue7: [Int] = [1, 3, 6] var valueOptions7 = ["One", "Two", "Three", "Four", "Five", "Six", "Seven"] var listPickerDataSource7 = StringListPickerDataSource(options: valueOptions7) override func viewDidLoad() { super.viewDidLoad() self.collectionView.register(FUIListPickerCollectionViewCell.self, forCellWithReuseIdentifier: FUIListPickerCollectionViewCell.reuseIdentifier) // ... } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIListPickerCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIListPickerCollectionViewCell cell.title.text = "Choose Multiple" cell.value = propValue7 cell.allowsMultipleSelection = true cell.valueText.text = descriptionForSelectedStrings(valueOptions7, at: propValue7) // See below cell.listPicker.dataSource = listPickerDataSource7 cell.listPicker.searchResultsUpdating = listPickerDataSource7 cell.listPicker.isSearchEnabled = true cell.listPicker.prompt = "Please select multiple items" cell.listPicker.searchBar?.isBarcodeScannerEnabled = true cell.listPicker.searchBar?.barcodeScanner?.scanMode = .EAN_UPC cell.listPicker.searchBar?.barcodeScanner?.scanResultTransformer = { (scanString) -> String in return self.transformStringToSearchBar(scanResultString: scanString) } // MARK: implement onChangeHandler cell.onChangeHandler = { [weak self] newValue in self.propValue3 = newValue } return cell } func descriptionForSelectedStrings(_ options: [String], at indexes: [Int]) -> String { return options.enumerated().filter({ (index, element) -> Bool in return indexes.contains(index) }).reduce ("") { string, element in return string.isEmpty ? element.1 : "\(string), \(element.1)" } }## Theming
Supported
Textclass paths:fdlFUIListPickerCollectionViewCell_title {} fdlFUIListPickerFormView_valueText {}Supported
Textattributes:font-color (Color) font-name (FontName) font-style (UIFontTextStyle) font-size (Number) text-align (TextAlign) text-line-clamp (Integer)Supported
UIViewclass paths:fdlFUIListPickerCollectionViewCell_selectedBackgroundView {}Supported
UIViewproperties:
See morebackground-color: (Color)Declaration
Swift
@MainActor open class FUIListPickerCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIListPickerFormView>, FUIPickerFormCell -
The reusable UI component implemented as a
UICollectionViewCell, allowing a user to select range values from the slider, which can be controlled using a single thumb or double thumbs.The developer should set the following properties on the cell in their implementation of the
UICollectionViewDataSourcecellForItem(at:)function:title: The key name of the property.minimumValue: The minimum value of the slider.maximumValue: The maximum value of the slider.- “
And an
onChangeHandler:onChangeHandler: a handler closure, which is invoked on changes to the value.
Optionally, the developer may provide
isEditable: Indicates whether the cell’s value can be modified. The default istrue.lowerValue: The minimum value the user can select.upperValue: The maximum value the user can select.isRangeSelection: Determines whether the slider should show one thumb or two thumbs. The default istrue.subtitle: the hint text.interval: the minimum value of the slider as it changes. The default is1.isContinuous: whether value change events are generated any time. The default istrue.
The following is an example of usage in an application,
UIViewController:override func viewDidLoad() { super.viewDidLoad() self.collectionView.register(FUIRangeSliderCollectionViewCell.self, forCellReuseIdentifier: FUIRangeSliderCollectionViewCell.reuseIdentifier) } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUIRangeSliderCollectionViewCell.reuseIdentifier, for: indexPath) as? FUIRangeSliderCollectionViewCell else { return UICollectionViewCell() } cell.title = "Range Label" cell.maximumValue = 50 cell.minimumValue = 10 cell.subtitle = "Hint Text" cell.isEditable = true cell.upperValue = 40 cell.lowerValue = 20 cell.isRangeSelection = true // MARK: implement onChangeHandler cell.onChangeHandler = { (lower, upper) in // ... } return cell }## Theming
nuiClass:fdlFUIRangeSliderFormCell {}Supported
keyView:fdlFUIRangeSliderFormCell_keyText { font-color { -highlighted | -disabled } (Color) font-style { -highlighted | -disabled } (UIFont.TextStyle) }Supported
slider:fdlFUIRangeSliderFormCell_slider { track-tint-color { -disabled } (Color); track-selection-color { -disabled } (Color); thumb-tint-color { -disabled } (Color); }Supported
textfields:fdlFUIRangeSliderFormCell_textFields { font-color { -disabled } (Color) font-style { -disabled } (UIFont.TextStyle) border-color { -highlighted | -readonly } (Color) }Supported
hintText:
See morefdlFUIRangeSliderFormCell_hintText { font-color { -disabled } (Color) font-style { -disabled } (UIFont.TextStyle) }Declaration
Swift
@MainActor open class FUIRangeSliderCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIRangeSliderContentView> -
A customized
UICollectionViewCellcontaining anFUISliderFormView. It allows users to select a single value from a continuous range of values.
The developer should set the following properties on the cell, in their implementation of
UICollectionViewDataSourcecellForItem(at:)function:title: The key name of the propertyvalue: The value of the property, asFloatminimumValue: The minimum value of the selection range.maximumValue: The maximum value of the selection range.
And an
onChangeHandler:onChangeHandler: a handler closure, which is invoked on changes to the value.
Optionally, the developer may set:
unit: The unit of value. Default isnil.formatter: The formatter to format the presentation of unit.isEditable: Indicates if the cell’s value may be modified. Defaults totrue.isContinuous: A Boolean value indicating whether changes in the slider’s value generate continuous update events.
The following is an example of usage in an application
UICollectionViewController:override func viewDidLoad() { super.viewDidLoad() self.collectionView.register(FUISliderCollectionViewCell, forCellReuseIdentifier: FUISliderCollectionViewCell.reuseIdentifier) // ... } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUISliderCollectionViewCell.reuseIdentifier, for: indexPath) as! FUISliderCollectionViewCell cell.title = "Distance" cell.minimumValue = 0 cell.maximumValue = 30 cell.value = 10 // MARK: implement an onChangeHandler cell.onChangeHandler = { [weak self] newValue in self.myObject.distance = newValue } return cell }Theming
Supported style classes
See moreFUISliderCollectionViewCell FUISliderCollectionViewCell_title FUISliderCollectionViewCell_subtitle FUISliderCollectionViewCell_footnote FUISliderCollectionViewCell_sliderDeclaration
Swift
@MainActor open class FUISliderCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUISliderFormView>, FUIFormCell -
FUIOrderPickerCollectionViewCellis aUICollectionViewCellsubclass that is used in the advanced sort pattern when there are multiple sort criteria involved. The component allows users to adjust the priority of sort criteria and flexibly switch order direction.## Usage Example:
let cell = collectionView.dequeueReusableCell(withIdentifier: FUIOrderPickerCollectionViewCell.reuseIdentifier, for: indexPath) as! FUIOrderPickerCollectionViewCell cell.value = [ FUISortCriterion(criterion: FUIMultiLineText("Priority"), isSelected: true, isAscending: false, ascendingText: FUIMultiLineText("Lowest first"), descendingText: FUIMultiLineText("Highest first")), FUISortCriterion(criterion: FUIMultiLineText("Name"), isSelected: false, isAscending: true, ascendingText: FUIMultiLineText("Ascending"), descendingText: FUIMultiLineText("Descending")) ] cell.onChangeHandler = { [unowned self] change, newValue in // change contains the info about immediate change to sort criterions // newValue contains the latest array of sort criterions } return cell // more customization options // change the title cell.title = FUIText("Order by", font: UIFont.preferredFioriFont(forTextStyle: .largeTitle), textColor: UIColor.preferredFioriColor(forStyle: .negativeLabel)) // change the selected icon for all sort criteria let config = UIImage.SymbolConfiguration(font: UIFont.preferredFioriFont(forTextStyle: .body)) let icon = UIImage(systemName: "checkmark.circle", withConfiguration: config) cell.selectedIcon = icon // change the appearance of labels in sort criterion with font, textColor and numberOfLines in FUIMultiLineText FUIMultiLineText("Priority", font: UIFont.preferredFioriFont(forTextStyle: .body), textColor: UIColor.purple) // other options cell.isAtLeastOneSelected = false cell.isContentCopyable = false## Theming
Supported
TEXTclass paths:fdlFUIOrderPickerFormCell_title fdlFUIOrderPickerFormItemCell_title {} fdlFUIOrderPickerFormItemCell_subtitle {}Supported
TEXTproperties:font-color: Color; font-style: UIFontTextStyle;Supported
IMAGEclass paths:fdlFUIOrderPickerFormItemCell_leadingImageView {}Supported
IMAGEproperties:image-name: UIImage; font-style: UIFontTextStyle; tint-color: UIColor;See Theming support in
See moreFUIOrderPickerFormViewandFUIOrderPickerFormItemView.Declaration
Swift
@MainActor public class FUIOrderPickerCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIOrderPickerFormView>, FUIContentCopyable, FUITableAndCollectionCellUpdate -
The reusable UI component implemented as a
UICollectionViewCell, including anFUIRatingControlto allow users to select a rating.This collection view cell uses
FUIRatingControlContentViewas its content view.FUIRatingControlContentViewincludes anFUITextKitViewfor hosting thekeyNameproperty, anFUIRatingControlfor the rating control, and anotherFUITextKitViewfor the subtitle.When the
textin thesubtitleis not nil, the title will not be displayed.Control Styles
you can set the available style for
FUIRatingControltoeditable,editableDisabled,standard, oraccented.Example
control.style = .editable control.ratingBounds = 0...5 control.rating = 3 control.onImage = UIImage(named: "filledStar").withRenderingMode(.alwaysTemplate) control.onImage = UIImage(named: "openStar").withRenderingMode(.alwaysTemplate) control.setTintColor(.orange, for: 0..<1) control.setTintColor(.red, for: 1..<5) control.setTintColor(.purple, for: 5..<6)Theming
nuiClass:fdlFUIRatingControlCollectionViewCell {}Supported
TEXTclass paths:fdlFUIRatingControlCollectionViewCell_title {}Supported
TEXTproperties:font-color: Color; font-style: UIFontTextStyle;Supported
FUIRatingControlclass path:fdlFUIRatingControlCollectionViewCell_ratingControlSupported
RatingControlproperties:
See moreon-color { -standard | -accented | -editable-disabled | -editable-disabled }: Color; off-color { -standard | -accented | -editable-disabled | -editable-disabled }: Color; on-image { -standard | -editable }: Image; off-image { -standard | -editable }: Image;Declaration
Swift
@MainActor open class FUIRatingControlCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIRatingControlContentView> -
Simple
UICollectionViewCellsubclass, containing aUIButtoninstance which can be aligned to 3FUIHorizontalAlignmentpositions:.left,.center,.right.Usage:
Implement the action handler for the
UIButtoninstance, to respond toUIControlevents.Theming
Supported
FUIButtonCollectionViewCellclass path:fdlFUIButtonCollectionViewCellSupported
BUTTONclass paths:
See morefdlFUIButtonCollectionViewCell_buttonDeclaration
Swift
@MainActor open class FUIButtonCollectionViewCell : FUIBaseDrawingCollectionViewCell<FUIButtonFormView>