Floorplan

  • A generic UITableViewController subclass for displaying business objects in a list context.

    Floorplan Structure

    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 an FUIListFloorplan, 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.
    See more

    Declaration

    Swift

    open class FUIListFloorplan<Entity, Section> : UITableViewController, UISearchResultsUpdating where Entity : Hashable, Entity : Identifiable, Section : CaseIterable, Section : Hashable
  • A generic UITableViewController subclass for displaying different properties of a business object.

    Floorplan Structure

    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 use sectionHeaderDidTapHandler and sectionFooterDidTapHandler.

    Theming

    Supported ObjectHeader class paths:

    fdlFUIObjectFloorplan_objectHeader

    Supported ObjectHeader attributes:

    Refer to FUIObjectHeader documentation for more information.

    See more

    Declaration

    Swift

    open class FUIObjectFloorplan<Entity> : UITableViewController, UICollectionViewDataSource, UICollectionViewDelegate where Entity : Hashable, Entity : Identifiable
  • The floorplan for editing a business object.

    Typically it should be used together with FUIObjectFloorplan. A use case would be presenting a FUIObjectEditingFloorplan when hitting the edit button in FUIObjectFloorplan.

    See more

    Declaration

    Swift

    public protocol FUIObjectEditingFloorplan : UIViewController
  • The section object which can be displayed in FUIObjectFloorplan. This is a base type and should not be used directly. Developer should use either FUIObjectListSection or FUIObjectCollectionSection.

    See more

    Declaration

    Swift

    public protocol FUIObjectSection
  • A section for showing a list of UITableViewCell or its variants.

    See more

    Declaration

    Swift

    public protocol FUIObjectListSection : FUIObjectSection
  • A section for showing a collection of UICollectionViewCell or its variants.

    See more

    Declaration

    Swift

    public protocol FUIObjectCollectionSection : FUIObjectSection
  • The generic-typed FUIListViewModel wrapping the data from a data query loader and providing state to the UI components.

    See more

    Declaration

    Swift

    public class FUIListViewModel<Entity, Section> : ObservableObject where Entity : Hashable, Entity : Identifiable, Section : CaseIterable, Section : Hashable
  • The generic-typed FUIDataLoader creates data queries on demand for a FUIListViewModel.

    See more

    Declaration

    Swift

    open class FUIDataLoader<Entity> : ObservableObject where Entity : Identifiable
  • A coordinator that can handle navigation between floorplans.

    See more

    Declaration

    Swift

    public protocol FUICoordinator : AnyObject
  • Represents a navigation step in generic floorplan.

    Declaration

    Swift

    public protocol FUIStep
  • A set of predefined steps for generic floorplan.

    See more

    Declaration

    Swift

    public enum FUIObjectStep : FUIStep