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:

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:

  1. Autolayout system, if estimatedItemSize is set not equal to CGSize.zero
  2. FUICollectionViewHorizontalFlowLayout, with numberOfColumns property, if minimumScaledItemSize is set not equal to CGSize.zero
  3. FUICollectionViewHorizontalFlowLayout, if minimumScaledItemSize is set not equal to CGSize.zero
  4. 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 to UIEdgeInsetsMake(0, 8, 0, 8).
  • UICollectionViewCell subclass used for displaying business objects in a collectionView.

    Developer should use the FUICollectionItemView and FUIBaseItemCollectionViewCell 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:

        tint-color: Color;
    
    See more

    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:

    tint-color: Color;
    
    See more

    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:

    tint-color: Color;
    
    See more

    Declaration

    Swift

    open class FUIImageCollectionItemView : FUIDrawingView, FUIDetailImageViewComponent
  • UICollectionViewCell subclass used for displaying business object’s image in a collectionView.

    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 a UICollectionView.

    Takes responsibility for correct layout and sizing for the items, for different screen dimensions.

    See more

    Declaration

    Swift

    open class FUIItemCollectionViewTableViewCell : FUIBaseCollectionViewTableViewCell
  • A variant of UICollectionViewCell which is very similar to SimplePropertyFormCell 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’s dataSource method collectionView(_: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

    fdlFUISimplePropertyCollectionViewCell
    fdlFUISimplePropertyCollectionViewCell_keyLabel
    fdlFUISimplePropertyCollectionViewCell_valueTextField
    
    See more

    Declaration

    Swift

    open class FUISimplePropertyCollectionViewCell : NibDesignableFUIBaseCollectionViewCell
  • FUIKeyValueCollectionViewCell is a variant of UICollectionViewCell defined in SAPFiori. It contains a UILabel and a UITextField.

    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:)

    
    public 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
    }
    
    
    See more

    Declaration

    Swift

    open class FUIKeyValueCollectionViewCell : NibDesignableFUIBaseCollectionViewCell
  • Set of UICollectionViewFlowLayouts occurring in Fiori Design Language.

    See more

    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’s contentSize.

    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 the contentSize width, by setting the numberOfColumns 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 and minimumLineSpacing 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

    1. Assign an instance of FUIHorizontalScrollCollectionViewLayout to your collection view.

      self.collectionView.collectionViewLayout = FUICollectionViewLayout.horizontalScroll
      
    2. 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
      }
      
    3. 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 more

    Declaration

    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

    1. Assign an instance of FUIHorizontalScrollCollectionViewLayout to your collection view.

      self.collectionView.collectionViewLayout = FUICollectionViewLayout.horizontalScroll
      
    2. 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
      }
      
    3. 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 more

    Declaration

    Swift

    open class FUIHorizontalScrollCollectionViewLayout : UICollectionViewFlowLayout
  • 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

    1. Assign an instance of FUIStandardAutoSizingColumnFlowLayout to your collection view.

      self.collectionView.collectionViewLayout = FUICollectionViewLayout.autosizingColumnFlow
      
    2. 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
      }
      
    3. 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 more

    Declaration

    Swift

    open class FUIStandardAutoSizingColumnFlowLayout : FUIBaseCollectionViewLayout<FUIStandardAutoSizingColumnSectionLayoutManager>
  • This layout is a variant of FUIHorizontalScrollCollectionViewLayout, which calculates cell size based on auto-resizing value returned from systemLayoutSizeFitting(_:). If all of your cells have the same size, use FUIHorizontalScrollCollectionViewLayout 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
    }
    
    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 and minimumLineSpacing 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. The FUICollectionViewTableViewCell will resize its height to accomodate all the items in collection view.

    See more

    Declaration

    Swift

    open class FUICollectionViewTableViewCell : NibDesignableFUIBaseTableViewCell