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:
FUITableViewCollectionSection
with embeddedFUICollectionViewTableViewCell
FUIAttachmentsController
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
estimatedItemSize
is set not equal toCGSize.zero
FUICollectionViewHorizontalFlowLayout
, withnumberOfColumns
property, ifminimumScaledItemSize
is set not equal toCGSize.zero
FUICollectionViewHorizontalFlowLayout
, ifminimumScaledItemSize
is set not equal toCGSize.zero
itemSize
property (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.
minimumInteritemSpacing
is set to 80.minimumLineSpacing
is set to 24.sectionInset
is set toUIEdgeInsetsMake(0, 8, 0, 8)
.
-
UICollectionViewCell
subclass used for displaying business objects in acollectionView
.Developer should use the
FUICollectionItemView
andFUIBaseItemCollectionViewCell
API 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 cell
Theming
nuiClass
:fdlFUIItemCollectionViewCell {}
Supported
TEXT
class paths:fdlFUIItemCollectionViewCell_title {} fdlFUIItemCollectionViewCell_subtitle {} fdlFUIItemCollectionViewCell_status {} fdlFUIItemCollectionViewCell_placeholder {}
Supported
TEXT
properties:font-color: Color; font-style: UIFontTextStyle; text-line-clamp: Integer; text-align: NSTextAlignment;
Supported
IMAGE
class paths:fdlFUIItemCollectionViewCell_detailImageView {}
Supported
IMAGE
properties:
See moretint-color: Color;
Declaration
Swift
@IBDesignable 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
TEXT
class paths:fdlFUICollectionItemView_title {} fdlFUICollectionItemView_subtitle {} fdlFUICollectionItemView_status {} fdlFUICollectionItemView_placeholder {}
Supported
TEXT
properties:font-color: Color; font-style: UIFontTextStyle; text-line-clamp: Integer; text-align: NSTextAlignment;
Supported
IMAGE
class paths:fdlFUICollectionItemView_detailImageView {}
Supported
IMAGE
properties:
See moretint-color: Color;
Declaration
Swift
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
IMAGE
class paths:fdlFUIImageCollectionItemView_detailImageView {}
Supported
IMAGE
properties:
See moretint-color: Color;
Declaration
Swift
open class FUIImageCollectionItemView : FUIDrawingView, FUIDetailImageViewComponent
-
UICollectionViewCell
subclass used for displaying business object’s image in acollectionView
.Developer should use the
FUIImageCollectionItemView
API 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 = true
Theming
nuiClass
:fdlFUIImageCollectionViewCell {}
Supported
IMAGE
class paths:fdlFUIImageCollectionViewCell_detailImageView {}
Supported
IMAGE
properties:tint-color: Color;
Declaration
Swift
open class FUIImageCollectionViewCell : FUIBaseItemCollectionViewCell<FUIImageCollectionItemView>
-
UITableViewCell
containing aUICollectionView
.Takes responsibility for correct layout and sizing for the items, for different screen dimensions.
See moreDeclaration
Swift
open class FUIItemCollectionViewTableViewCell : FUIBaseCollectionViewTableViewCell
-
A variant of
UICollectionViewCell
which is very similar toSimplePropertyFormCell
except that it’s not editable.keyName
: The key of the cell.value
: The value of the cell.
Code usage:
Register
FUISimplePropertyCollectionViewCell
for a collection view object.self.collectionView.register(FUISimplePropertyCollectionViewCell.self, forCellWithReuseIdentifier: FUISimplePropertyCollectionViewCell.reuseIdentifier)
Dequeue a
FUISimplePropertyCollectionViewCell
object from a collection view’sdataSource
methodcollectionView(_: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_valueTextField
Declaration
Swift
open class FUISimplePropertyCollectionViewCell : NibDesignableFUIBaseCollectionViewCell
-
FUIKeyValueCollectionViewCell is a variant of
UICollectionViewCell
defined inSAPFiori
. It contains aUILabel
and aUITextField
.Code usage:
Register
FUIKeyValueCollectionViewCell
for 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
open class FUIKeyValueCollectionViewCell : NibDesignableFUIBaseCollectionViewCell
-
Set of
See moreUICollectionViewFlowLayout
s 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
contentSize
width, or, may set a pre-determined number of items which ought to fit thecontentSize
width, by setting thenumberOfColumns
property. 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
minimumInteritemSpacing
andminimumLineSpacing
values 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.horizontalScroll
Implement 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
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
itemSize
property 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.horizontalScroll
Implement 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
open class FUIHorizontalScrollCollectionViewLayout : UICollectionViewLayout
-
The
FUIStandardAutoSizingColumnFlowLayout
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.Code usage
Assign an instance of FUIStandardAutoSizingColumnFlowLayout to your collection view.
self.collectionView.collectionViewLayout = FUICollectionViewLayout.autosizingColumnFlow
Implement 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
open class FUIStandardAutoSizingColumnFlowLayout : FUIBaseCollectionViewLayout<FUIStandardAutoSizingColumnSectionLayoutManager>
-
This layout is a variant of F
UIHorizontalScrollCollectionViewLayout
, which calculates cell size based on auto-resizing value returned from systemLayoutSizeFitting(_:). If all of your cells have the same size, useFUIHorizontalScrollCollectionViewLayout
instead.Code usage
Assign an instance of FUIHorizontalScrollDynamicSizeCollectionViewLayout to your collection view and do any configuration you need.
let layout = FUICollectionViewLayout.horizontalScrollDynamicSize self.collectionView.collectionViewLayout = layout self.collectionView.register(FUICollectionItemCell.self, forCellWithReuseIdentifier: FUICollectionItemCell.reuseIdentifier)
Implement collectionView(_:cellForItemAt:) dataSource.
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUICollectionItemCell.reuseIdentifier, for: indexPath) as! FUICollectionItemCell //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) }
Declaration
Swift
@available(*, deprecated, message: "Use `FUIHorizontalScrollCollectionViewLayout` and set `estimatedItemSize` to a non-zero value to enable auto-sizing.") open class FUIHorizontalScrollDynamicSizeCollectionViewLayout : FUIHorizontalScrollCollectionViewLayout
-
A subclass of
FUIStandardAutoSizingColumnFlowLayout
which 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.minimumInteritemSpacing
is set to 80 andminimumLineSpacing
is set to 24 by default.sectionInset
is set to ‘top: 0, left: 8, bottom: 0, right: 8’.Declaration
Swift
public class FUIKeyValueFlowLayout : FUIStandardAutoSizingColumnFlowLayout
-
UITableViewCell
subclass, containing a full-frame collectionView. TheFUICollectionViewTableViewCell
will 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
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
UITableViewDataSource
cellForRow(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
UIViewController
andUICollectionViewDataSource
: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_switch
described above is preferable to the version offdlFUISwitchFormCell_switch
described below (to achieve maximum UX design compliance).
See morefdlFUISwitchFormCell_switch { tint-color on-tint-color }
Declaration
Swift
open class FUISwitchCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUISwitchFormView>
-
FUIInlineSignatureCollectionViewCell
is aUICollectionViewCell
subclass 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 cell
Theming
See Theming support in
See moreFUIInlineSignatureFormView
.Declaration
Swift
public class FUIInlineSignatureCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIInlineSignatureFormView>, FUITableAndCollectionCellUpdate
-
The reusable UI component implemented as a
UICollectionViewCell
to 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
tintAttributes
Supported
keyView
:setAttributes([.foregroundColor:, .font], for: .title, state: { .normal | .highlighted | .disabled })
or directly set
textColor
andfont
for the title.Supported
valueText
:setAttributes([.foregroundColor:, .font], for: .valueText, state: { .normal | .disabled }) addAttributes([.fuiBorderColor:], for: .valueText, state: { .normal | .highlighted | .disabled })
or directly set
textColor
andfont
for the valueTextField.Supported
increaseButton
anddecreaseButton
:setAttributes([.foregroundColor:], for: .icons, state: { .normal | .disabled })
Supported
hintView
:setAttributes([.foregroundColor:, .font:], for: .subtitle, state: { .normal | .disabled })
###
.nss
ThemeSupported
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
BUTTON
class 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
open class FUIStepperCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIStepperView>, FUIFormCell
extension FUIStepperCollectionViewCell: FUITintAttributesProvider
-
The reusable UI component implemented as a
UICollectionViewCell
to display a key-value pair property, which is integrated with aFUIListPicker
controller 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
: TheFUIListPicker
for thisFUIListPickerCollectionViewCell
.
Note that the display of the selections in the
valueLabel
is the responsibility of the developer if thedataSource
property of thelistPicker
is set. The developer needs to set the text of thevalueLabel
to reflect the selections. Otherwise, if the developer setsvalueOptions
and leavesdataSource
oflistPicker
asnil
, then the text invalueLabel
will be set internally.Here are the code snippets in the app’s
UICollectionViewController
implementation: (The app’sUICollectionViewController
needs 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
Text
class paths:fdlFUIListPickerCollectionViewCell_title {} fdlFUIListPickerFormView_valueText {}
Supported
Text
attributes:font-color (Color) font-name (FontName) font-style (UIFontTextStyle) font-size (Number) text-align (TextAlign) text-line-clamp (Integer)
Supported
UIView
class paths:fdlFUIListPickerCollectionViewCell_selectedBackgroundView {}
Supported
UIView
properties:
See morebackground-color: (Color)
Declaration
Swift
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
UICollectionViewDataSource
cellForItem(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
open class FUIRangeSliderCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIRangeSliderContentView>
-
A customized
UICollectionViewCell
containing 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
UICollectionViewDataSource
cellForItem(at:)
function:title
: The key name of the propertyvalue
: The value of the property, asFloat
minimumValue
: 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_slider
Declaration
Swift
open class FUISliderCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUISliderFormView>, FUIFormCell
-
FUIOrderPickerCollectionViewCell
is aUICollectionViewCell
subclass 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
TEXT
class paths:fdlFUIOrderPickerFormCell_title fdlFUIOrderPickerFormItemCell_title {} fdlFUIOrderPickerFormItemCell_subtitle {}
Supported
TEXT
properties:font-color: Color; font-style: UIFontTextStyle;
Supported
IMAGE
class paths:fdlFUIOrderPickerFormItemCell_leadingImageView {}
Supported
IMAGE
properties:image-name: UIImage; font-style: UIFontTextStyle; tint-color: UIColor;
See Theming support in
See moreFUIOrderPickerFormView
andFUIOrderPickerFormItemView
.Declaration
Swift
public class FUIOrderPickerCollectionViewCell : FUIBaseDrawingCollectionViewCell<FUIOrderPickerFormView>, FUIContentCopyable, FUITableAndCollectionCellUpdate
-
The reusable UI component implemented as a
UICollectionViewCell
, including anFUIRatingControl
to allow users to select a rating.This collection view cell uses
FUIRatingControlContentView
as its content view.FUIRatingControlContentView
includes anFUITextKitView
for hosting thekeyName
property, anFUIRatingControl
for the rating control, and anotherFUITextKitView
for the subtitle.When the
text
in thesubtitle
is not nil, the title will not be displayed.Control Styles
you can set the available style for
FUIRatingControl
toeditable
,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
TEXT
class paths:fdlFUIRatingControlCollectionViewCell_title {}
Supported
TEXT
properties:font-color: Color; font-style: UIFontTextStyle;
Supported
FUIRatingControl
class path:fdlFUIRatingControlCollectionViewCell_ratingControl
Supported
RatingControl
properties:
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
open class FUIRatingControlCollectionViewCell : FUIInlineValidationDrawingCollectionViewCell<FUIRatingControlContentView>
-
Simple
UICollectionViewCell
subclass, containing aUIButton
instance which can be aligned to 3FUIHorizontalAlignment
positions:.left
,.center
,.right
.Usage:
Implement the action handler for the
UIButton
instance, to respond toUIControl
events.Theming
Supported
FUIButtonCollectionViewCell
class path:fdlFUIButtonCollectionViewCell
Supported
BUTTON
class paths:
See morefdlFUIButtonCollectionViewCell_button
Declaration
Swift
open class FUIButtonCollectionViewCell : FUIBaseDrawingCollectionViewCell<FUIButtonFormView>