Floorplan
-
A generic
UITableViewController
subclass for displaying business objects in a list context.Floorplan Structure
- On the top of view is
FUIGridTableViewHeader
(optional). - Under the header, to display a list of entities, a standard table view is implemented using
FUIEditableTableViewDiffableDataSource
. By default the list view supports features including pull to refresh, global search, and pagination control.
Usage
View Model Binding
An
FUIListViewModel
manages the data pipeline between the list floorplan and data query loader. It also controls how paginated list results are displayed and the global search function. When initializing anFUIListFloorplan
, it is required to set up a view model. The floorplan informs the view model whenever there is a request of new entities query, meanwhile it also observes state changes exposed by the view model.var queries: [ProductListReportSections: FUIDataLoader<Product>] = [:] queries[.default] = ProductDataLoader() let model = FUIListViewModel<Product, ProductListReportSections>(queries: queries, isListPagingEnabled: true, isSearchEnabled: true) let floorplan = FUIListFloorplan<Product, ProductListReportSections>(viewModel: model)
Cell Binding
A
cellBinding
closure may be used to custom the display of table view cells bound with different entities.floorplan.cellBinding = { tableView, indexPath, entity in let cell = tableView.dequeueReusableCell(withIdentifier: FUIObjectTableViewCell.reuseIdentifier, for: indexPath) as! FUIObjectTableViewCell entity.bind(to: cell) return cell }
Pull & Drag Interaction
By default
FUIListFloorplan
supports pagination in an infinite scroll pattern.- Pull to refresh is implemented using standard
UIRefreshControl
. - Infinite scrolling with paginated display is triggered by the
scrollViewDidEndDragging
delegate. An initial list will be displayed when the floorplan is displayed. When user scrolls to the end of the list, entities for the next page will be fetched and display. During the data fetching period, a loading indicator will be animating in the footer area of the list view.
Search Control
- Change
searchDebounceTiming
to add a delay before actual initiating of search requests to a data query loader. - Implement
emptyResultsView
to display a custom empty state view when the search result is empty.
Tap Action Handling
- Implement
addButtonDidTapHandler
to handle the tap action on add button. - Implement
deleteButtonDidTapHandler
to handle the tap action on delete button.
Declaration
Swift
open class FUIListFloorplan<Entity, Section> : UITableViewController, UISearchResultsUpdating where Entity : Hashable, Entity : Identifiable, Section : CaseIterable, Section : Hashable
- On the top of view is
-
A generic
UITableViewController
subclass for displaying different properties of a business object.Floorplan Structure
- On the top of view is
FUIObjectHeader
(optional) - Under the header, any number of
FUIObjectSection
can be added. There are two types of sections are supported:FUIObjectListSection
: A section to show a list ofUITableViewCell
or its variants.FUIObjectCollectionSection
: A section to show a collection ofUICollectionViewCell
or its variants. Default collection view layout used isFUICollectionViewLayout.horizontalScrollDynamicSize
. Developer can set their own layout object if needed.
Usage
Data Binding
// Closure for object header data binding let objectHeaderBinding: ((Product, FUIObjectHeader) -> Void)? = { _, objectHeader in objectHeader.headlineText = "Three Phase Pad Mounted Transformer (533423)" objectHeader.subheadlineText = "Electric Asset 533423" objectHeader.bodyText = "Three Phase Pad Mounted Transformer (533423)" objectHeader.footnoteText = "Temperature sensor predicts overheating failure in 4 days" objectHeader.statusText = "Available" objectHeader.detailImage = #imageLiteral(resourceName: "attachment009.5") } // List section definition class LocationSection: FUIObjectListSection { lazy var cellProvider: ((AnyTableBasedFloorplan, IndexPath, AnyHashable) -> UITableViewCell)? = { floorplan, indexPath, element in let cell = floorplan.base.tableView.dequeueReusableCell(withIdentifier: FUIObjectTableViewCell.reuseIdentifier, for: indexPath) as! FUIObjectTableViewCell // set properties for object cell return cell } var cellTypeAndReuseIdentifier: (AnyClass, String) { return (FUIObjectTableViewCell.self, FUIObjectTableViewCell.reuseIdentifier) } } // Collection section definition class ProductComponentsSection: FUIObjectCollectionSection { var elements: [AnyHashable] lazy var cellProvider: ((AnyTableBasedFloorplan, UICollectionView, IndexPath, AnyHashable) -> UICollectionViewCell)? = { _, collectionView, indexPath, element in let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MyThumbnailCollectionViewCell.reuseIdentifier, for: indexPath) as! MyThumbnailCollectionViewCell // set properties for MyThumbnailCollectionViewCell return cell } lazy var headerProvider: ((AnyTableBasedFloorplan, Int) -> UITableViewHeaderFooterView)? = { [unowned self] floorplan, _ in let header = floorplan.base.tableView.dequeueReusableHeaderFooterView(withIdentifier: FUITableViewHeaderFooterView.reuseIdentifier) as! FUITableViewHeaderFooterView header.style = .title header.titleLabel.text = "Subcomponents" return header } var cellTypeAndReuseIdentifier: (AnyClass, String) { return (MyThumbnailCollectionViewCell.self, MyThumbnailCollectionViewCell.reuseIdentifier) } init(components: [String]) { self.elements = components } } let objectFloorplan = FUIObjectFloorplan(object: Product(), style: .grouped, objectHeaderProvider: objectHeaderBinding) objectFloorplan.sectionsProvider = { _ in return [ LocationSection(), ProductComponentsSection(components: components) ] }
Tap action handling
Implement
elementDidTapHandler
to handle the tap action on section elements. For header and footer usesectionHeaderDidTapHandler
andsectionFooterDidTapHandler
.Theming
Supported
ObjectHeader
class paths:fdlFUIObjectFloorplan_objectHeader
Supported
ObjectHeader
attributes:Refer to
See moreFUIObjectHeader
documentation for more information.Declaration
Swift
open class FUIObjectFloorplan<Entity> : UITableViewController, UICollectionViewDataSource, UICollectionViewDelegate where Entity : Hashable, Entity : Identifiable
- On the top of view is
-
The floorplan for editing a business object.
Typically it should be used together with
See moreFUIObjectFloorplan
. A use case would be presenting aFUIObjectEditingFloorplan
when hitting theedit
button inFUIObjectFloorplan
.Declaration
Swift
public protocol FUIObjectEditingFloorplan : UIViewController
-
The section object which can be displayed in
See moreFUIObjectFloorplan
. This is a base type and should not be used directly. Developer should use eitherFUIObjectListSection
orFUIObjectCollectionSection
.Declaration
Swift
public protocol FUIObjectSection
-
A section for showing a list of
See moreUITableViewCell
or its variants.Declaration
Swift
public protocol FUIObjectListSection : FUIObjectSection
-
A section for showing a collection of
See moreUICollectionViewCell
or its variants.Declaration
Swift
public protocol FUIObjectCollectionSection : FUIObjectSection
-
The generic-typed
See moreFUIListViewModel
wrapping the data from a data query loader and providing state to the UI components.Declaration
Swift
public class FUIListViewModel<Entity, Section> : ObservableObject where Entity : Hashable, Entity : Identifiable, Section : CaseIterable, Section : Hashable
-
The generic-typed
See moreFUIDataLoader
creates data queries on demand for aFUIListViewModel
.Declaration
Swift
open class FUIDataLoader<Entity> : ObservableObject where Entity : Identifiable
-
A coordinator that can handle navigation between floorplans.
See moreDeclaration
Swift
public protocol FUICoordinator : AnyObject
-
Represents a navigation step in generic floorplan.
Declaration
Swift
public protocol FUIStep