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.
A common usage is to create a table view with multiple FUIGridTableViewCell
s representing different rows for showing a list report. Each cell(row) has a collection of FUIGridRowItem
s. 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:
FUIGridRowHeaderItem
- representing a header for a column.FUIGridRowTextItem
- representing a text or number item. Assign aNumberFormatter
instance toFUIGridRowTextItem
if you want to format textual representation of the number.FUIGridRowImageItem
- representing an image item.
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.
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 extendsUITableViewHeaderFooterView
for showing a list ofFUIGridRowItem
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 forregular
andcompact
horizontal content modes. It is hidden by design, when incompact
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 ofFUIGridRowTextItem
for representing a header item inFUIGridTableViewCell
.FUIGridRowHeaderItem
is different fromFUIGridRowTextItem
in terms of style.Theming
Supported style classes
See morefdlFUIGridRowHeaderItem_label
Declaration
Swift
open class FUIGridRowHeaderItem : FUIGridRowTextItem
-
FUIGridTableViewCell
is aUITableViewCell
subclass used to display data in a ‘column-based’ table, such as a spreadsheet table. Each row is configured by a list ofFUIGridRowItem
instances. The cells adapt betweenregular
andcompact
horizontal mode, to switch from column-based layout inregular
mode, to an ‘object-view’ layout incompact
mode.A
binding
is automatically generated for each row item, to an associatedtext
orimage
type of property in the object view layout. A developer may customize these bindings, and choose to bind only a subset of columns, using thebinding
property on theFUIGridRowImageItem
orFUIGridRowTextItem
. 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
, andfootnote
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 thatstatus
andstatusImage
are in the same group, as well assubstatus
andsubstatusImage
. Only one of them can be displayed at a time. For example, if the fourth text item is mapped tostatus
, the image item next to it in the row will be mapped tosubstatusImage
instead ofstatusImage
. - 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 in0.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 cellfdlFUIGridTableViewCell_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 theUIViewController.willTransitionTo(size:)
method, orviewDidAppear()
.Example:
See moreoverride func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) DispatchQueue.main.async { self.tableView.beginUpdates() self.tableView.endUpdates() } }
Declaration
Swift
open class FUIGridTableViewCell : FUIBaseDrawingTableViewCell<FUIObjectView>, FUIAccessoryViewDelegate, FUIContentCopyable
- The first three text item will be mapped to
-
A protocol defines style of a
See moreFUIGridRowItem
.Declaration
Swift
public protocol FUIGridRowItem : AnyObject
-
An enum representing the different item styles that a
See moreFUIGridRowItem
can have.Declaration
Swift
public enum FUIGridRowItemType
-
The vertical layout of grid row items in the row.
See moreDeclaration
Swift
public enum FUIGridRowItemAlignment : Int
-
The
FUIGridRowImageItem
is a subclass ofFUIImageView
which conforms toFUIGridRowItem
protocol for representing a image item inFUIGridTableViewCell
.Theming
Supported style classes
See morefdlFUIGridRowImageItem
Declaration
Swift
open class FUIGridRowImageItem : FUIImageView, FUIGridRowItem, FUIGridRowItemBinding
-
The
FUIGridRowTextItem
conforms toFUIGridRowItem
protocol which contains aUILabel
for representing a text/number item inFUIGridTableViewCell
. Setting a NumberFormatter if you want to format the number.Theming
Supported style classes
See morefdlFUIGridRowTextItem_label fdlFUIGridRowTextItem_font_firstTextItem
Declaration
Swift
open class FUIGridRowTextItem : FUIGridRowItem, FUIGridRowItemBinding