List Floorplan (Tools Example)¶
The list report floorplan is one flat list that contains objects of the same object type. It may contain one or multiple groups. The user can view each object and take actions from the list report—for instance, grouping them. The user may filter to create a separate list.
Here is a sample of how to implement the example in the Tools example:
In this sample, we will:
- Bind the model to views in the controller
- Set up Search functionality
- Utilize the Barcode Scanner, integrated in the
SearchBar
(requires a physical device, with camera)
Bind the Model to Views in the Controller¶
The most common UITableViewCell
utilized in List Reports is the FUIObjectTableViewCell
. Set up an array of Tool
objects, and bind that data to a dequeued FUIObjectTableViewCell
.
Be sure to set the tableView.rowHeight = UITableViewAutomaticDimension
, so that the AutoLayout
system will correctly calculate the height of the table view cells from their content.
class ToolsListReportFloorplanExample: UITableViewController {
var tools: [ToolsListReportFPData.Tool] = ToolsListReportFPData.tools // see sample model data below
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Tools"
self.tableView.register(FUIObjectTableViewCell.self, forCellReuseIdentifier: FUIObjectTableViewCell.reuseIdentifier)
self.tableView.estimatedRowHeight = 98
self.tableView.rowHeight = UITableViewAutomaticDimension
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tools.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let task = tools[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: FUIObjectTableViewCell.reuseIdentifier,
for: indexPath) as! FUIObjectTableViewCell
cell.headlineText = tool.title
cell.subheadlineText = tool.code
cell.detailImage = tool.image
cell.descriptionText = tool.description
cell.statusText = tool.status
cell.accessoryType = .disclosureIndicator
return cell
}
Depending on how your navigation hierarchy is configured, you might notice that your Navigation Bar does not display. If this is the case, ensure that a
UINavigationController
is active, and controlling the presentation of your view controller. If you have set up a Single-Page Application, you should select your view controller in your storyboard, and select Editor > Embed In > Navigation Controller. For more details, see Apple Documentation.
Set up Search Functionality¶
Use the SAPFiori framework subclasses UISearchController
and UISearchBar
, to natively integrate bar code scanning into the search bar. You can use the FUISearchBar
without barcode scanning, also, as shown below:
-
Configure the
FUISearchController
, and setFUISearchBar
toUITableView
tableHeaderView
subview propertyclass ToolsListReportFloorplanExample: UITableViewController, UISearchResultsUpdating { var searchController: FUISearchController! var tools: [ToolsListReportFPData.Tool] = ToolsListReportFPData.tools override func viewDidLoad() { super.viewDidLoad() self.title = "Tools" self.tableView.register(FUIObjectTableViewCell.self, forCellReuseIdentifier: FUIObjectTableViewCell.reuseIdentifier) searchController = FUISearchController(searchResultsController: nil) searchController.searchResultsUpdater = self searchController.searchBar.placeholderText = "Search for tool" self.tableView.tableHeaderView = searchController.searchBar self.tableView.estimatedRowHeight = 98 self.tableView.rowHeight = UITableViewAutomaticDimension }
-
Create an
isFiltered
flag, andfilteredTools
data source to use while filtering on search bar inputclass ToolsListReportFloorplanExample: UITableViewController, UISearchResultsUpdating { var searchController: FUISearchController! var tools: [ToolsListReportFPData.Tool] = ToolsListReportFPData.tools var filteredTools: [ToolsListReportFPData.Tool] = [] var isFiltered: Bool = false override func viewDidLoad() { super.viewDidLoad() self.title = "Tools" self.tableView.register(FUIObjectTableViewCell.self, forCellReuseIdentifier: FUIObjectTableViewCell.reuseIdentifier) searchController = FUISearchController(searchResultsController: nil) searchController.searchResultsUpdater = self searchController.searchBar.placeholderText = "Search for tool" self.tableView.tableHeaderView = searchController.searchBar self.tableView.estimatedRowHeight = 98 self.tableView.rowHeight = UITableViewAutomaticDimension } // MARK: - Table view data source override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return isFiltered ? filteredTools.count : tools.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let tool = isFiltered ? filteredTools[indexPath.row] : tools[indexPath.row] let cell = tableView.dequeueReusableCell(withIdentifier: FUIObjectTableViewCell.reuseIdentifier, for: indexPath) as! FUIObjectTableViewCell cell.headlineText = tool.title cell.subheadlineText = tool.code cell.detailImage = tool.image cell.descriptionText = tool.description cell.statusText = tool.status cell.accessoryType = .disclosureIndicator return cell }
-
Implement
UIKit
UISearchResultsUpdating
protocol, to respond to changes to theUISearchBar
input// MARK: UISearchResultsUpdating func updateSearchResults(for searchController: UISearchController) { guard let searchString = searchController.searchBar.text, !searchString.isEmpty else { self.isFiltered = false self.filteredTools.removeAll() self.tableView.reloadData() return } self.isFiltered = true self.filteredTools = self.tools.filter( { return $0.title.contains(searchString) || $0.code.contains(searchString) || $0.description.contains(searchString) }) self.tableView.reloadData() }
Configure the Embedded Barcode Scanner¶
The Barcode Scanner depends on access to the device camera. According to Apple's privacy requirements, a developer must add the following entry to the application project's Info.plist; if missing, the application will be terminated when the user attempts to launch a camera-dependent component.
1 2 3 4 |
|
class ToolsListReportFloorplanExample: UITableViewController, UISearchResultsUpdating {
var searchController: FUISearchController!
var tools: [ToolsListReportFPData.Tool] = ToolsListReportFPData.tools
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Tools"
self.tableView.register(FUIObjectTableViewCell.self, forCellReuseIdentifier: FUIObjectTableViewCell.reuseIdentifier)
searchController = FUISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.searchBar.placeholderText = "Search for tool"
searchController.searchBar.isBarcodeScannerEnabled = true
searchController.hidesNavigationBarDuringPresentation = true
searchController.searchBar.barcodeScanner?.scanResultTransformer = {
return $0.lowercased()
}
self.tableView.tableHeaderView = searchController.searchBar
self.tableView.estimatedRowHeight = 98
self.tableView.rowHeight = UITableViewAutomaticDimension
}
Sample Data¶
Before running the application, add an image to your project's Asset catalog, named
"BoringPic"
. For more information on working with Asset catalogs, see Apple documentation.
struct ToolsListReportFPData {
struct Tool {
let title: String
let code: String
let image: UIImage?
let description: String
let status: String
init(title: String, code: String, image: UIImage? = UIImage(named: "BoringTool"), description: String = "Cylinder head - CYLH-Z6-R166 / Index 2", status: String = "OP50") {
self.title = title
self.code = code
self.image = image
self.description = description
self.status = status
}
}
static let tools: [Tool] = [Tool(title: "PCBN Indexable Insert Boring Tool", code: "T6179"),
Tool(title: "Special PCD Milling Cutter", code: "T6171"),
Tool(title: "Special PCD Stepped Boring Tool", code: "T5277"),
Tool(title: "Special PCD Stepped Boring Tool", code: "T5278"),
Tool(title: "Special PCD Stepped Boring Tool", code: "T4370"),
Tool(title: "Special PCD Stepped Boring Tool", code: "T4270"),
Tool(title: "Special PCD Stepped Boring Tool", code: "T4271"),
Tool(title: "Special PCD Stepped Boring Tool", code: "T4272"),
Tool(title: "Special PCD Stepped Boring Tool", code: "T4273"),
Tool(title: "Special PCD Stepped Boring Tool", code: "T4371")]
}