Timeline views

The FUITimelineCell and FUITimelineMarkerCell are Interface-Builder-designable UITableViewCell controls, used to construct the Timeline View, which presents information or events in chronological order.

Image

The FUITimelinePreviewTableViewCell is an Interface-Builder-designable UI component that extends NibDesignableTableViewCell which contains a FUITimelinePreviewView. It resizes itself to fit content using the auto-layout size of FUITimelinePreviewView.

Image

The FUITimelinePreviewView shows an excerpt of your project’s milestones in a convenient linear visual presentation. By default, each task node is ordered by date and can be classified as open, complete, or end. Timeline Preview augments task management by prioritizing overdue tasks as well as tasks closest to their due date but not yet marked as complete. This implementation aims to present the most pressing issues to the top of your task queue. Timeline Preview is supported across all currently supported Apple iOS devices.

Image

Interface

FUITimelineCell

  • FUITimelineCell is a selectable cell intended for timelines that require open and complete status that displays timeline details. Selecting the cell changes the card background color to the framework-preferred color: FioriUIColorStyle.line.
  • It uses a vertical line and nodeImageView as a separator. Left of the vertical line is the timeline event stack view that contains eventLabel and eventImageView; right of the vertical line is the main stack view that contains headlineLabel and subheadlineLabel.
  • Below the main view is an attribute stack view with attributeLabel and subAttributeLabel laid out horizontally.
  • To the right of the main view is a status view that contains statusLabel, statusImage, substatusLabel, and substatusImage laid out vertically.

FUITimelineMarkerCell

  • FUITimelineMarkerCell is a non-selectable cell with selectionStyle set to .none that is intended for timelines with start, inactive, early end, and end status that displays timeline information.
  • It uses a vertical line and a node image as a separator. Left of the vertical line is the timeline event section that contains eventLabel and eventImageView; right of the vertical line is titleLabel.
  • The vertical line contains leadingTimeline on the top, nodeImageView in the middle, and a trailingTimeline at the bottom.

Usage

A FUITimelineCell can be used freely within any UITableView:

Register the FUITimelineCell and FUITimelineMarkerCell controls in the viewDidLoad function:


    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(FUITimelineCell.self, forCellReuseIdentifier: FUITimelineCell.reuseIdentifier)
        tableView.register(FUITimelineMarkerCell.self, forCellReuseIdentifier: FUITimelineMarkerCell.reuseIdentifier)
        // ...
    }

Initialize and configure cells in tableView(_:cellForRowAt:):

Though both options are marked public, you should always use the Text: String and Image: UIImage properties to set cell content, instead of directly setting values to the @IBOutlet. This allows the implementation to optimize the constraints for the given content. It is fine to set other properties of the @IBOutlet, such as font style or color, opacity, etc.


    let cell = tableView.dequeueReusableCell(withIdentifier: FUITimelineCell.reuseIdentifier, for: indexPath) as! FUITimelineCell
    cell.headlineText = "Planned Downtime Period Identified"
    cell.subheadlineText = "Work Package"
    cell.nodeImage = FUITimelineNode.open
    cell.eventText = "9:45\nAM"
    cell.eventImage = #imageLiteral(resourceName: "rain")
    cell.statusImage = #imageLiteral(resourceName: "ErrorIcon")
    cell.subStatusText = "Active"
    return cell


    let cell = tableView.dequeueReusableCell(withIdentifier: FUITimelineMarkerCell.reuseIdentifier, for: indexPath) as! FUITimelineMarkerCell
    cell.titleText = "Project Start"
    cell.nodeImage = FUITimelineNode.start
    cell.eventText = "12/6/15"
    cell.showLeadingTimeline = false
    return cell


    //Your data model
    var data: [FUITimelineItem] {
    let item0 = FUITimelineItem()
    item0.title = "Planned Downtime Period Identified for Tasks"
    item0.due = Date(timeIntervalSinceNow: -86400 * 2) // 86400 sec equal to 1 day
    item0.status = .complete

    let item1 = FUITimelineItem()
    item1.title = "UX Design Review"
    item1.due = Date(timeIntervalSinceNow: -86400)
    item1.status = .open

    let item2 = FUITimelineItem()
    item2.title = "Planned Downtime Period Identified for Tasks"
    item2.due = Date()
    item2.status = .open

    let item3 = FUITimelineItem()
    item3.title = "UX Design Review"
    item3.due = Date(timeIntervalSinceNow: 86400)
    item3.status = .open

    let item4 = FUITimelineItem()
    item4.title = "Project End"
    item4.due = Date(timeIntervalSinceNow: 86400 * 2.0)
    item4.status = .end

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

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

    cell.timelinePreviewView.header.titleLabel.text = "Timeline"
    cell.timelinePreviewView.header.attributeLabel.text = "attribute"
    cell.timelinePreviewView.header.isDisclosureAccessoryHidden = false
    cell.timelinePreviewView.header.didSelectHandler = {
        print("header is selected")
    }

    cell.timelinePreviewView.addItems(data)
    cell.timelinePreviewView.numberOfColumns = 4 //set numberOfColumns if you want to change number of columns showing

    return cell
    }
  • FUITimelineCell is a UITableViewCell subclass designed to present a business object related to an event in a Timeline view.

    Timeline Cell

    • FUITimelineCell is a selectable cell intended for timelines that require open and complete status that displays timeline details. Selecting the cell changes the card background color to the framework-preferred color.
    • It uses a vertical line and nodeImageView as a separator. To the left of the vertical line is the timeline event stack view that contains eventLabel and eventImageView. To the right of the vertical line is the main stack view that contains headlineLabel and subheadlineLabel.
    • Below the main view is an attribute stack view with attributeLabel and subAttributeLabel laid out horizontally.
    • To the right of the main view is a status view that contains statusLabel, statusImage, substatusLabel, and substatusImage laid out vertically.

    ## Usage

     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     let cell = tableView.dequeueReusableCell(withIdentifier: "FUITimelineCell", for: indexPath) as! FUITimelineCell
     cell.headlineText = "Planned Downtime Period Identified"
     cell.subheadlineText = "Work Package"
     cell.nodeType = .open
     cell.eventText = "9:45\nAM"
     cell.eventImage = #imageLiteral(resourceName: "rain")
     cell.statusImage = #imageLiteral(resourceName: "ErrorIcon")
     cell.subStatusText = "Active"
     return cell
     }
    

    ## Notes

    ### SingleLine Separator Between Timeline Items in the Table Tableview‘s default separatorStyle is .singleLine. Because of this default setting, there can be a 1.0 px divider line or a separator in between each item on the timeline in the table. This is not an issue in timeline. To get rid of the separator, set separatorStyle to none in the TabelViewController class.

     override func viewDidLoad() {
     super.viewDidLoad()
     //...
     self.tableView.separatorStyle = .none
     //...
     }
    

    ### Customize the Background Color

    Developers may use the backgroundColor property of timelineBackground and cardBackground to set the background color, and use the setTintColor(_:_:) UITableViewCell API to customize the card background in highlighted and completed states.

     timelineCell.timelineBackground.backgroundColor = UIColor.orange
     timelineCell.cardBackground.backgroundColor = UIColor.yellow // For normal background
     timelineCell.setTintColor(UIColor.red, for: .highlighted) // For highlighted state background
     timelineCell.setTintColor(UIColor.green, for: .application) // For completed state background
    

    ## Theming Supported style classes

     fdlFUITimelineCell
     fdlFUITimelineCell_headlineLabel
     fdlFUITimelineCell_subheadlineLabel
     fdlFUITimelineCell_timestampLabel
     fdlFUITimelineCell_secondaryTimestampLabel
     fdlFUITimelineCell_statusLabel
     fdlFUITimelineCell_substatusLabel
     fdlFUITimelineCell_attributeLabel
     fdlFUITimelineCell_subattributeLabel
     fdlFUITimelineCell_nodeImageView
     fdlFUITimelineCell_timelineBackground
     fdlFUITimelineCell_cardBackground
     fdlFUITimelineCell_cardBackground_past
     fdlFUITimelineCell_cardBackground_highlighted
    
    See more

    Declaration

    Swift

    @IBDesignable
    open class FUITimelineCell : NibDesignableFUIBaseTableViewCell, FUIStyleSheetAttributesApplying
  • FUITimelineMarkerCell is a UITableViewCell subclass, designed to present a business object related to an event, in a Timeline view.

    Timeline Marker Cell

    • FUITimelineMarkerCell is a non-selectable with selectionStyle set to .none that is intended for timelines with start, inactive, early end, and end status that display timeline information.
    • It uses a vertical line and a node image as a separator. Left to the vertical line is the timeline event section that contains eventLabel and eventImageView; right to the vertical line is titleLabel.
    • The vertical line contains leadingTimeline on the top, nodeImageView in the middle, and a trailingTimeline at the bottom.

    ## Usage

    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FUITimelineMarkerCell", for: indexPath) as! FUITimelineMarkerCell
        cell.titleText = "Project Start"
        cell.nodeType = .start
        cell.eventText = "12/6/15"
        cell.showLeadingTimeline = false
        return cell
    }
    
    

    ## Notes ### SingleLine Separator Between Timeline Items in the Table The default table view separatorStyle is .singleLine. Because of this default setting, there can be a 1.0 px divider line or a separator in-between each item on the timeline in the table. This is not an issue in timeline. To get rid of the separator, set separatorStyle to none in the TabelViewController class

    
     override func viewDidLoad() {
        super.viewDidLoad()
        // ...
        self.tableView.separatorStyle = .none
        // ...
     }
    
    

    ## Theming Supported style classes

     fdlFUITimelineMarkerCell
     fdlFUITimelineMarkerCell_titleLabel
     fdlFUITimelineMarkerCell_eventLabel
     fdlFUITimelineMarkerCell_eventImageView
     fdlFUITimelineMarkerCell_nodeImageView
     fdlFUITimelineMarkerCell_cardBackground
     fdlFUITimelineMarkerCell_timelineBackground
    
    See more

    Declaration

    Swift

    open class FUITimelineMarkerCell : NibDesignableFUIBaseTableViewCell, FUIStyleSheetAttributesApplying
  • FUITimelinePreviewView is an Interface-Builder-designable UI component that extends UIView for showing a collection of tasks. It comes with a header and a collection view which uses FUITimelineCollectionViewCell to represent data items within it.

    Using addItems() to populate a collection of FUITimelineItem object.

    Views Available in FUIObjectCell:

    Rules for displaying tasks:

    • Timeline shows all items due but not marked complete. If there are Overdue objects, this will be shown first until it is marked complete. ‘Today’ will come in the timeline preview only if there is something due ‘Today’.

    • When the last object is the only one left on the timeline, the Project end date will be visible as the last milestone. The gradient for the horizontal line will switch to right to left.

    • Once the end of the timeline is visible and due and overdue tasks do not fill all the columns, the completed tasks will start to fill the available columns.

    • If there is an object due on the last day of the project, it will show as the Open Node, until it is marked complete. Then it will switch to the ‘Complete Node.’ The gradient for the horizontal line will switch to right to left.

    Example Initialization and Configuration:

    let timelinePreviewView = FUITimelinePreviewView()
    
    timelinePreviewView.header.titleLabel.text = "Timeline"
    timelinePreviewView.header.attributeLabel.text = "attribute"
    timelinePreviewView.header.isDisclosureAccessoryHidden = false
    timelinePreviewView.header.didSelectHandler = {
    // do something when disclosure indicator is tapped
    }
    
    let item0 = FUITimelineItem()
    item0.title = "Planned Downtime Period Identified for Tasks"
    item0.due = Date(timeIntervalSinceNow: -86400 * 2)
    item0.status = .complete
    
    let item1 = FUITimelineItem()
    item1.title = "UX Design Review"
    item1.due = Date(timeIntervalSinceNow: -86400)
    item1.status = .open
    
    timelinePreviewView.addItems([item0, item1])
    

    theming

    fdlFUITimelinePreviewView_header {
       font-style: subheadline;
       font-color: @primary2;
    }
    
    See more

    Declaration

    Swift

    @IBDesignable
    open class FUITimelinePreviewView : UIView, UICollectionViewDataSource
  • FUITimelinePreviewTableViewCell is an Interface-Builder-designable UI component that extends NibDesignableTableViewCell which contains a FUITimelinePreviewView. It resizes itself to fit content using the auto-layout size of FUITimelinePreviewView.

    Views Available in FUIObjectTableViewCell:

    Example Initialization and Configuration:

    var data: [FUITimelineItem] {
    let item0 = FUITimelineItem()
    item0.title = "Planned Downtime Period Identified for Tasks"
    item0.due = Date(timeIntervalSinceNow: -86400 * 2) // 86400 sec equal to 1 day
    item0.status = .complete
    
    let item1 = FUITimelineItem()
    item1.title = "UX Design Review"
    item1.due = Date(timeIntervalSinceNow: -86400)
    item1.status = .open
    
    let item2 = FUITimelineItem()
    item2.title = "Planned Downtime Period Identified for Tasks"
    item2.due = Date()
    item2.status = .open
    
    let item3 = FUITimelineItem()
    item3.title = "UX Design Review"
    item3.due = Date(timeIntervalSinceNow: 86400)
    item3.status = .open
    
    let item4 = FUITimelineItem()
    item4.title = "Project End"
    item4.due = Date(timeIntervalSinceNow: 86400 * 2.0)
    item4.status = .end
    
    return [item0, item1, item2, item3, item4]
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: FUITimelinePreviewTableViewCell.reuseIdentifier, for: indexPath) as! FUITimelinePreviewTableViewCell
    
    cell.timelinePreviewView.header.titleLabel.text = "Timeline"
    cell.timelinePreviewView.header.attributeLabel.text = "attribute"
    cell.timelinePreviewView.header.isDisclosureAccessoryHidden = false
    cell.timelinePreviewView.header.didSelectHandler = {
    }
    
    // If you want to display other styles than date, for example, Time.
    let formatter = DateFormatter()
    formatter.dateFormat = "hh:mm"
    cell.timelinePreviewView.dateFormatter = formatter
    
    cell.timelinePreviewView.addItems(data)
    
    return cell
    }
    
    

    theming

    fdlFUITimelinePreviewTableViewCell {
    background-color: @clear;
    }
    fdlFUITimelinePreviewTableViewCell_selected {
    background-color: @line;
    }
    
    See more

    Declaration

    Swift

    @IBDesignable
    open class FUITimelinePreviewTableViewCell : NibDesignableFUIBaseTableViewCell
  • FUITimelineItem is an item specialized for placement in FUITimelinePreviewView.

    See more

    Declaration

    Swift

    open class FUITimelineItem : NSObject
  • FUITimelinePreviewNode is a variant of FUITimelineNode which defines framework-supplied images for various timeline node status values in FUITimelineCollectionViewCell.

    Usage

    
    let nodeImage = FUITimelinePreviewNode.open
    
    

    Theming

    Supported style classes

    fdlFUITimelinePreviewNode
    fdlFUITimelinePreviewNode_inactive_outerImage
    fdlFUITimelinePreviewNode_inactive_innerImage
    fdlFUITimelinePreviewNode_inactive_borderImage
    fdlFUITimelinePreviewNode_complete_outerImage
    fdlFUITimelinePreviewNode_complete_innerImage
    fdlFUITimelinePreviewNode_complete_icon
    fdlFUITimelinePreviewNode_start_outerImage
    fdlFUITimelinePreviewNode_start_innerImage
    fdlFUITimelinePreviewNode_open_outerImage
    fdlFUITimelinePreviewNode_open_innerImage
    fdlFUITimelinePreviewNode_open_borderImage
    fdlFUITimelinePreviewNode_end_outerImage
    fdlFUITimelinePreviewNode_end_innerImage
    fdlFUITimelinePreviewNode_earlyEnd_outerImage
    fdlFUITimelinePreviewNode_earlyEnd_innerImage
    
    See more

    Declaration

    Swift

    public struct FUITimelinePreviewNode
  • The status of FUITimelineItem.

    See more

    Declaration

    Swift

    public enum FUITimelineStatus : Int
  • FUITimelineCollectionViewCell is an Interface-Builder-designable UI component that extends NibDesignableCollectionViewCell for showing information of a task. FUITimelinePreviewView embeds a collection view which displays a set of FUITimelineCollectionViewCell.

    Views Available in FUITimelineCollectionViewCell:

    • titleLabel: an UILabel showing a short description of the task.

    • footnoteLabel: anUILabel showing extra information about the task. When cell is used with a FUITimelinePreviewView, the textual representation of due date of FUITimelineItem is put here.

    • nodeImageView: anUIImageView contains a node image showing the status of the task. You change the node type by setting ‘nodeType’ on FUITimelineCollectionViewCell.

    Example Initialization and Configuration:

    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FUITimelineCollectionViewCell.reuseIdentifier, for: indexPath) as! FUITimelineCollectionViewCell
    
    cell.title = "Development Kick-off"
    cell.footnote = Date()
    cell.nodeType = .open
    
    return cell
    }
    

    theming

    fdlFUITimelineCollectionViewCell_titleLabel {
       font-style: subheadline;
       font-color: primary1;
    }
    
    fdlFUITimelineCollectionViewCell_footnoteLabel {
       font-style: footnote;
       font-color: primary3;
    }
    
    See more

    Declaration

    Swift

    @IBDesignable
    open class FUITimelineCollectionViewCell : NibDesignableCollectionViewCell
  • The FUITimelineCollectionViewHorizontalFlowLayout is a subclass of FUIStandardAutoSizingColumnFlowLayout which resizes collection view cell items, to lay them out according to a specified number of columns. All items on the same row are resized to have identical cell height using the height of the tallest cell in that row.

    See more

    Declaration

    Swift

    open class FUITimelineCollectionViewHorizontalFlowLayout : FUIStandardAutoSizingColumnFlowLayout