Grid view

FUIGridTableViewCell

FUIGridTableViewCell is a Fiori UI component that extends UITableViewCell for showing a list of FUIGridRowItem horizontally. By default, cell height is determined by the auto-layout system height of the tallest item in the cell. Row items will be vertically center aligned if cell only contains single-line text items. Otherwise, row items will be top aligned. Column width is configurable by assigning a fixed width or percent width. You can also have dynamic column in the cell by assigning value of -1 to that column. At most one column can be dynamic.

Image

A common usage is to create a table view with multiple FUIGridTableViewCells representing different rows for showing a list report. Each cell(row) has a collection of FUIGridRowItems. Each column in the table view can bind with a FUIGridrowHeaderItem to represent a type of data. SAPFiori provides three types of row items which conform to FUIGridRowItem protocol:

Image

Example Initialization and Configuration of FUIGridTableViewCell

Register FUIGridTableViewCell for Table View. Set UITableViewAutomaticDimension to rowHeight if You Want Cell Height to Be Dynamic

override open func viewDidLoad() {
super.viewDidLoad()
tableView.register(FUIGridTableViewCell.self, forCellReuseIdentifier: FUIGridTableViewCell.reuseIdentifier)
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 100
tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = 100
tableView.register(FUIGridTableViewHeader.self, forHeaderFooterViewReuseIdentifier: FUIGridTableViewHeader.reuseIdentifier)
}

Override tableView(_:cellForRowAt:) dataSource Method and Configure Cell

//data model
var contentData: [FUIGridRowItem] {

let item0 = FUIGridRowImageItem(image: #imageLiteral(resourceName: "ProfilePic"))

let item1 = FUIGridRowTextItem(text: "PM01 PM01")

let item2 = FUIGridRowTextItem(number: 31.00)

let item3 = FUIGridRowTextItem(number: 31.00)

let item4 = FUIGridRowTextItem(number: 31.00)

let item5 = FUIGridRowTextItem(number: 31.00)

return [item0, item1, item2, item3, item4, item5]
}

var headerData: [FUIGridRowItem] {
let item0 = FUIGridRowHeaderItem(text: " ")

let item1 = FUIGridRowHeaderItem(text: "Product Name")

let item2 = FUIGridRowHeaderItem(text: "Model")

let item3 = FUIGridRowHeaderItem(text: "Category")

let item4 = FUIGridRowHeaderItem(text: "Availability")

let item5 = FUIGridRowHeaderItem(text: "Price")

return [item0, item1, item2, item3, item4, item5]
}

override open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: FUIGridTableViewCell.reuseIdentifier, for: indexPath) as! FUIGridTableViewCell

if let data = displayedData?[indexPath.row] {
cell.gridItems = data.gridItems
cell.tag = data.index
cell.columnWidthPercent = columnWidthPercent
cell.accessoryType = .disclosureIndicator
}

return cell
}

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: FUIGridTableViewHeader.reuseIdentifier) as! FUIGridTableViewHeader

header.gridItems = self.header?.gridItems
header.columnWidthPercent = columnWidthPercent
header.accessoryType = .disclosureIndicator

return header
}

FUIGridTableViewHeader

FUIGridTableViewHeader is a Fiori UI component that extends UITableViewHeaderFooterView for showing a list of FUIGridRowItem horizontally. It will display as a section header in table view. By default, header height is determined by the auto-layout system height of the tallest item in the cell. Row items will be vertically center aligned if cell only contains single-line text items. Otherwise, row items will be top aligned.

Setting column width by assigning a fixed width or percentage for each column. You can also have dynamic column in the cell by assigning value of -1 to that column. At most one column can be dynamic.

Image

Example Initialization and Configuration of FUIGridTableViewHeader

Register FUIGridTableViewHeader for Table View. Set UITableViewAutomaticDimension to rowHeight if You Want Cell Height to Be Dynamic

override open func viewDidLoad() {
super.viewDidLoad()
tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = 100
tableView.register(FUIGridTableViewHeader.self, forHeaderFooterViewReuseIdentifier: FUIGridTableViewHeader.reuseIdentifier)
}

Override tableView(_: viewForHeaderInSection:) DataSource Method and Configure Cell

//data model
var headerData: [FUIGridRowItem] {
let item0 = FUIGridRowHeaderItem(text: " ")

let item1 = FUIGridRowHeaderItem(text: "Product Name")

let item2 = FUIGridRowHeaderItem(text: "Model")

let item3 = FUIGridRowHeaderItem(text: "Category")

let item4 = FUIGridRowHeaderItem(text: "Availability")

let item5 = FUIGridRowHeaderItem(text: "Price")

return [item0, item1, item2, item3, item4, item5]
}

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: FUIGridTableViewHeader.reuseIdentifier) as! FUIGridTableViewHeader

header.gridItems = self.header?.gridItems
header.columnWidthPercent = columnWidthPercent
header.accessoryType = .disclosureIndicator

return header
}
  • FUIGridTableViewHeader is a Fiori UI component that extends UITableViewHeaderFooterView for showing a list of FUIGridRowItem column titles. It will display as a section header in table view.

    Columns widths may be specified in absolute points, or as a set of fractions in 0.0..<1. A developer may also designate one column for flexible width, by assigning the value -1 to that column width.

    Remark

    Developers should always use the same column widths or percents for all headers, footers and rows in a grid. Developers should also set common accessory types to rows, headers and footers.

    The FUIGridTableViewHeader is adaptive for regular and compact horizontal content modes. It is hidden by design, when in compact mode. The AutoLayout automatic dimension technique should be used for computing the header height.

    Example Initialization and Configuration:

    override open func viewDidLoad() {
    super.viewDidLoad()
    tableView.sectionHeaderHeight = UITableViewAutomaticDimension
    tableView.estimatedSectionHeaderHeight = 100
    tableView.register(FUIGridTableViewHeader.self, forHeaderFooterViewReuseIdentifier: FUIGridTableViewHeader.reuseIdentifier)
    }
    

    Override tableView(_: viewForHeaderInSection:) dataSource method and configure header.

    // header data list
    var headerData: [FUIGridRowItem] {
    let item0 = FUIGridRowHeaderItem(text: " ")
    let item1 = FUIGridRowHeaderItem(text: "Symbol")
    let item2 = FUIGridRowHeaderItem(text: "Open")
    let item3 = FUIGridRowHeaderItem(text: "High")
    let item4 = FUIGridRowHeaderItem(text: "Low")
    let item5 = FUIGridRowHeaderItem(text: "Close")
    return [item0, item1, item2, item3, item4, item5]
    }
    
    // set column widths.  Should be shared by rows and header.
    let columnWidths = [-1, 0.2, 0.1, 0.1, 0.1, 0.1]
    
    // configure header view
    header.items = headerData
    header.columnWidthPercent = columnWidths
    header.accessoryType = .disclosureIndicator // match row cell accessory types!
    
    

    Declaration

    Swift

    open class FUIGridTableViewHeader : FUIGridTableViewHeaderFooterView
  • The FUIGridRowHeaderItem is a subclass of FUIGridRowTextItem for representing a header item in FUIGridTableViewCell. FUIGridRowHeaderItem is different from FUIGridRowTextItem in terms of style.

    Theming

    Supported style classes

    fdlFUIGridRowHeaderItem_label
    
    See more

    Declaration

    Swift

    open class FUIGridRowHeaderItem : FUIGridRowTextItem
  • FUIGridTableViewCell is a UITableViewCell subclass used to display data in a ‘column-based’ table, such as a spreadsheet table. Each row is configured by a list of FUIGridRowItem instances. The cells adapt between regular and compact horizontal mode, to switch from column-based layout in regular mode, to an ‘object-view’ layout in compact mode.

    A binding is automatically generated for each row item, to an associated text or image type of property in the object view layout. A developer may customize these bindings, and choose to bind only a subset of columns, using the binding property on the FUIGridRowImageItem or FUIGridRowTextItem. The default binding behavior if none of row items is supplied with binding is:

    • The first three text item will be mapped to headline, subheadline, and footnote of object view, respectively.
    • The first image item will be mapped to detailImage.
    • Subsequent text and image items will be mapped to status, statusImage, substatus, substatusImage on a “first-come, first-served” pattern. Note that status and statusImage are in the same group, as well as substatus and substatusImage. Only one of them can be displayed at a time. For example, if the fourth text item is mapped to status, the image item next to it in the row will be mapped to substatusImage instead of statusImage.
    • The image item will not be mapped to icon in any case, so the developer needs to explicitly set it if this is required.

    In regular mode, columns’ widths may be specified in absolute points, or as a set of fractions in 0.0..<1. A developer may also designate one column for flexible width, by assigning the value -1 to that column width.

    Row content will center-align vertically if all row items have a single line of text; rows with multiple lines of text will be top-aligned.

    Important: In order for FUIGridTableViewCell to work, the developer must enable auto dimension in table view. Cell height is determined by the content size in each column.

    override open func viewDidLoad() {
       super.viewDidLoad()
       tableView.sectionHeaderHeight = UITableViewAutomaticDimension
       tableView.estimatedSectionHeaderHeight = 100
    }
    

    Remark

    Developers are responsible for ensuring that the column widths supplied do not exceed the available dimensions.

    Example Initialization and Configuration:

    // row data list
    var contentData: [FUIGridRowItem] {
        let item0 = FUIGridRowImageItem(image: <#my image#>))
        let item1 = FUIGridRowTextItem(text: "SAP")
        let item2 = FUIGridRowTextItem(number: 114.23)
        let item3 = FUIGridRowTextItem(number: 114.84)
        let item4 = FUIGridRowTextItem(number: 113.92)
        let item5 = FUIGridRowTextItem(number: 114.76)
        return [item0, item1, item2, item3, item4, item5]
    }
    
    // header data list
    var headerData: [FUIGridRowItem] {
        let item0 = FUIGridRowHeaderItem(text: " ")
        let item1 = FUIGridRowHeaderItem(text: "Symbol")
        let item2 = FUIGridRowHeaderItem(text: "Open")
        let item3 = FUIGridRowHeaderItem(text: "High")
        let item4 = FUIGridRowHeaderItem(text: "Low")
        let item5 = FUIGridRowHeaderItem(text: "Close")
        return [item0, item1, item2, item3, item4, item5]
    }
    
    // set column widths. Should be shared by rows and header.
    let columnWidths = [-1, 0.2, 0.1, 0.1, 0.1, 0.1]
    
    // configure row cell
    cell.items = contentData
    cell.columnWidthPercent = columnWidths
    cell.accessoryType = .disclosureIndicator
    
    
    // configure header view
    header.items = headerData
    header.columnWidthPercent = columnWidths
    header.accessoryType = .disclosureIndicator
    
    

    Theming

    In the .nss file you can use the following parameters:

    • fdlFUIGridTableViewCell: changes the background of the cell
    • fdlFUIGridTableViewCell_selected: changes the selected background of the cell

    Example:

    fdlFUIGridTableViewCell {
       background-color: clear;
    }
    fdlFUIGridTableViewCell_selected {
       background-color: @line;
    }
    

    Handle Layout on View Controller Rotation

    It is uncommon, but sometimes the state of the view controller will require you to ask the table view to recalculate the grid layout. This could occur if a new view controller is pushed onto the stack, the user rotates the device, then pops the top view controller, returning to the grid.

    To avoid issues related to the state of the view controller, use the UITableView.beginUpdates() API to recompute the cell heights. Depending on the state condition, this should be done in the UIViewController.willTransitionTo(size:) method, or viewDidAppear().

    Example:

    override func viewDidAppear(_ animated: Bool) {
       super.viewDidAppear(animated)
    
       DispatchQueue.main.async {
           self.tableView.beginUpdates()
           self.tableView.endUpdates()
       }
    }
    
    See more

    Declaration

    Swift

    open class FUIGridTableViewCell : FUIBaseDrawingTableViewCell<FUIObjectView>, FUIAccessoryViewDelegate, FUIContentCopyable